summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/bus.c3
-rw-r--r--drivers/acpi/glue.c1
-rw-r--r--drivers/acpi/processor_idle.c14
-rw-r--r--drivers/atm/horizon.c4
-rw-r--r--drivers/base/firmware_class.c15
-rw-r--r--drivers/base/platform.c73
-rw-r--r--drivers/block/acsi.c1
-rw-r--r--drivers/block/cciss.c228
-rw-r--r--drivers/block/cciss.h11
-rw-r--r--drivers/block/cciss_scsi.c80
-rw-r--r--drivers/block/floppy.c8
-rw-r--r--drivers/block/pktcdvd.c2
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/agp/ali-agp.c1
-rw-r--r--drivers/char/agp/amd-k7-agp.c1
-rw-r--r--drivers/char/agp/amd64-agp.c18
-rw-r--r--drivers/char/agp/ati-agp.c1
-rw-r--r--drivers/char/agp/efficeon-agp.c1
-rw-r--r--drivers/char/agp/i460-agp.c1
-rw-r--r--drivers/char/agp/intel-agp.c1
-rw-r--r--drivers/char/agp/nvidia-agp.c1
-rw-r--r--drivers/char/agp/sis-agp.c1
-rw-r--r--drivers/char/agp/sworks-agp.c1
-rw-r--r--drivers/char/agp/uninorth-agp.c5
-rw-r--r--drivers/char/agp/via-agp.c1
-rw-r--r--drivers/char/epca.c1
-rw-r--r--drivers/char/ftape/lowlevel/ftape-buffer.c1
-rw-r--r--drivers/char/i8k.c6
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c8
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c2
-rw-r--r--drivers/char/pcmcia/Kconfig24
-rw-r--r--drivers/char/pcmcia/Makefile2
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c2078
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c841
-rw-r--r--drivers/char/pcmcia/cm4040_cs.h47
-rw-r--r--drivers/char/s3c2410-rtc.c50
-rw-r--r--drivers/char/sonypi.c19
-rw-r--r--drivers/char/synclink.c32
-rw-r--r--drivers/char/synclinkmp.c1
-rw-r--r--drivers/char/tb0219.c15
-rw-r--r--drivers/char/tpm/Kconfig2
-rw-r--r--drivers/char/tpm/tpm.c16
-rw-r--r--drivers/char/tpm/tpm.h7
-rw-r--r--drivers/char/tpm/tpm_atmel.c125
-rw-r--r--drivers/char/tpm/tpm_atmel.h131
-rw-r--r--drivers/char/vr41xx_giu.c15
-rw-r--r--drivers/char/vr41xx_rtc.c17
-rw-r--r--drivers/char/watchdog/booke_wdt.c2
-rw-r--r--drivers/char/watchdog/mpcore_wdt.c30
-rw-r--r--drivers/char/watchdog/mv64x60_wdt.c20
-rw-r--r--drivers/char/watchdog/pcwd_pci.c1
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c30
-rw-r--r--drivers/char/watchdog/wdt_pci.c1
-rw-r--r--drivers/hwmon/hdaps.c62
-rw-r--r--drivers/i2c/busses/i2c-ali1535.c1
-rw-r--r--drivers/i2c/busses/i2c-ali1563.c1
-rw-r--r--drivers/i2c/busses/i2c-ali15x3.c1
-rw-r--r--drivers/i2c/busses/i2c-amd756.c1
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c1
-rw-r--r--drivers/i2c/busses/i2c-hydra.c1
-rw-r--r--drivers/i2c/busses/i2c-i801.c1
-rw-r--r--drivers/i2c/busses/i2c-i810.c1
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c27
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c25
-rw-r--r--drivers/i2c/busses/i2c-ixp4xx.c32
-rw-r--r--drivers/i2c/busses/i2c-mpc.c24
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c24
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c1
-rw-r--r--drivers/i2c/busses/i2c-piix4.c1
-rw-r--r--drivers/i2c/busses/i2c-prosavage.c1
-rw-r--r--drivers/i2c/busses/i2c-pxa.c25
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c71
-rw-r--r--drivers/i2c/busses/i2c-savage4.c1
-rw-r--r--drivers/i2c/busses/i2c-sis5595.c1
-rw-r--r--drivers/i2c/busses/i2c-sis630.c1
-rw-r--r--drivers/i2c/busses/i2c-sis96x.c1
-rw-r--r--drivers/i2c/busses/i2c-via.c1
-rw-r--r--drivers/i2c/busses/i2c-viapro.c1
-rw-r--r--drivers/i2c/busses/i2c-voodoo3.c1
-rw-r--r--drivers/i2c/chips/isp1301_omap.c21
-rw-r--r--drivers/ide/Kconfig6
-rw-r--r--drivers/ide/Makefile2
-rw-r--r--drivers/ide/mips/Makefile1
-rw-r--r--drivers/ide/mips/swarm.c201
-rw-r--r--drivers/ide/pci/sl82c105.c83
-rw-r--r--drivers/ide/ppc/pmac.c11
-rw-r--r--drivers/ide/setup-pci.c12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c1
-rw-r--r--drivers/input/keyboard/corgikbd.c29
-rw-r--r--drivers/input/keyboard/spitzkbd.c29
-rw-r--r--drivers/input/serio/i8042.c19
-rw-r--r--drivers/input/serio/rpckbd.c21
-rw-r--r--drivers/input/touchscreen/corgi_ts.c32
-rw-r--r--drivers/isdn/hisax/Kconfig12
-rw-r--r--drivers/isdn/hisax/hfc_usb.c32
-rw-r--r--drivers/isdn/pcbit/Kconfig2
-rw-r--r--drivers/md/bitmap.c4
-rw-r--r--drivers/md/md.c36
-rw-r--r--drivers/media/common/ir-common.c60
-rw-r--r--drivers/media/dvb/b2c2/Kconfig1
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c9
-rw-r--r--drivers/media/video/Kconfig14
-rw-r--r--drivers/media/video/Makefile5
-rw-r--r--drivers/media/video/bttv-cards.c24
-rw-r--r--drivers/media/video/bttv-driver.c4
-rw-r--r--drivers/media/video/bttv-gpio.c18
-rw-r--r--drivers/media/video/bttv.h3
-rw-r--r--drivers/media/video/bttvp.h2
-rw-r--r--drivers/media/video/cx25840/Makefile6
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c368
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c1020
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c167
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c315
-rw-r--r--drivers/media/video/cx25840/cx25840.h85
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c3
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c3
-rw-r--r--drivers/media/video/ir-kbd-gpio.c292
-rw-r--r--drivers/media/video/ir-kbd-i2c.c52
-rw-r--r--drivers/media/video/saa7115.c1376
-rw-r--r--drivers/media/video/saa711x.c1
-rw-r--r--drivers/media/video/saa7127.c849
-rw-r--r--drivers/media/video/saa7134/Kconfig3
-rw-r--r--drivers/media/video/saa7134/Makefile7
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c448
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c32
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c121
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c109
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c161
-rw-r--r--drivers/media/video/saa7134/saa7134.h2
-rw-r--r--drivers/media/video/tda8290.c4
-rw-r--r--drivers/media/video/tuner-core.c11
-rw-r--r--drivers/media/video/tuner-simple.c4
-rw-r--r--drivers/media/video/wm8775.c7
-rw-r--r--drivers/mfd/mcp-sa11x0.c32
-rw-r--r--drivers/misc/hdpuftrs/hdpu_cpustate.c20
-rw-r--r--drivers/misc/hdpuftrs/hdpu_nexus.c20
-rw-r--r--drivers/mmc/mmci.c1
-rw-r--r--drivers/mmc/pxamci.c42
-rw-r--r--drivers/mmc/wbsd.c34
-rw-r--r--drivers/mtd/maps/Kconfig2
-rw-r--r--drivers/mtd/maps/bast-flash.c33
-rw-r--r--drivers/mtd/maps/integrator-flash.c23
-rw-r--r--drivers/mtd/maps/ixp2000.c25
-rw-r--r--drivers/mtd/maps/ixp4xx.c25
-rw-r--r--drivers/mtd/maps/omap_nor.c23
-rw-r--r--drivers/mtd/maps/plat-ram.c68
-rw-r--r--drivers/mtd/maps/sa1100-flash.c36
-rw-r--r--drivers/mtd/nand/s3c2410.c77
-rw-r--r--drivers/net/3c509.c13
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/au1000_eth.c1
-rw-r--r--drivers/net/bnx2.c16
-rw-r--r--drivers/net/depca.c26
-rw-r--r--drivers/net/dm9000.c35
-rw-r--r--drivers/net/e100.c275
-rw-r--r--drivers/net/fec_8xx/Kconfig2
-rw-r--r--drivers/net/forcedeth.c231
-rw-r--r--drivers/net/gianfar.c30
-rw-r--r--drivers/net/gianfar.h2
-rw-r--r--drivers/net/gianfar_ethtool.c2
-rw-r--r--drivers/net/gianfar_mii.c4
-rw-r--r--drivers/net/gianfar_mii.h2
-rw-r--r--drivers/net/gt96100eth.c10
-rw-r--r--drivers/net/ibmveth.c2
-rw-r--r--drivers/net/ioc3-eth.c2
-rw-r--r--drivers/net/irda/ali-ircc.c1
-rw-r--r--drivers/net/irda/nsc-ircc.c1
-rw-r--r--drivers/net/irda/sa1100_ir.c28
-rw-r--r--drivers/net/irda/smsc-ircc2.c27
-rw-r--r--drivers/net/jazzsonic.c21
-rw-r--r--drivers/net/macsonic.c21
-rw-r--r--drivers/net/mv643xx_eth.c40
-rw-r--r--drivers/net/r8169.c6
-rw-r--r--drivers/net/saa9730.c613
-rw-r--r--drivers/net/saa9730.h36
-rw-r--r--drivers/net/smc91x.c55
-rw-r--r--drivers/net/smc91x.h48
-rw-r--r--drivers/net/spider_net.c1
-rw-r--r--drivers/net/sungem.c2
-rw-r--r--drivers/net/tokenring/proteon.c17
-rw-r--r--drivers/net/tokenring/skisa.c17
-rw-r--r--drivers/net/wan/hdlc_cisco.c6
-rw-r--r--drivers/net/wan/hdlc_fr.c4
-rw-r--r--drivers/net/wan/hdlc_generic.c6
-rw-r--r--drivers/net/wan/sdladrv.c2
-rw-r--r--drivers/net/wireless/Kconfig2
-rw-r--r--drivers/net/wireless/atmel.c88
-rw-r--r--drivers/net/wireless/atmel.h4
-rw-r--r--drivers/net/wireless/atmel_cs.c176
-rw-r--r--drivers/net/wireless/atmel_pci.c2
-rw-r--r--drivers/net/wireless/hermes.c6
-rw-r--r--drivers/net/wireless/hermes.h6
-rw-r--r--drivers/net/wireless/i82593.h11
-rw-r--r--drivers/net/wireless/ipw2100.c29
-rw-r--r--drivers/net/wireless/ipw2100.h2
-rw-r--r--drivers/net/wireless/ipw2200.c7
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c4
-rw-r--r--drivers/parisc/iosapic.c26
-rw-r--r--drivers/parisc/superio.c35
-rw-r--r--drivers/pci/access.c2
-rw-r--r--drivers/pci/hotplug/pciehp.h135
-rw-r--r--drivers/pci/hotplug/pciehp_core.c108
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c1979
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c115
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c840
-rw-r--r--drivers/pci/hotplug/pciehprm.h52
-rw-r--r--drivers/pci/hotplug/pciehprm_acpi.c1727
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.c464
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.h56
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c79
-rw-r--r--drivers/pci/hotplug/rpaphp.h2
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c76
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c2
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c2
-rw-r--r--drivers/pci/msi.c20
-rw-r--r--drivers/pci/pci-acpi.c11
-rw-r--r--drivers/pci/pci-driver.c11
-rw-r--r--drivers/pci/pci.c46
-rw-r--r--drivers/pci/quirks.c19
-rw-r--r--drivers/pcmcia/cs.c6
-rw-r--r--drivers/pcmcia/ds.c3
-rw-r--r--drivers/pcmcia/i82365.c20
-rw-r--r--drivers/s390/char/raw3270.c4
-rw-r--r--drivers/s390/net/lcs.c4
-rw-r--r--drivers/s390/net/qeth.h77
-rw-r--r--drivers/s390/net/qeth_main.c261
-rw-r--r--drivers/s390/net/qeth_mpc.c2
-rw-r--r--drivers/s390/net/qeth_mpc.h13
-rw-r--r--drivers/s390/net/qeth_sys.c8
-rw-r--r--drivers/s390/net/qeth_tso.h2
-rw-r--r--drivers/sbus/char/display7seg.c2
-rw-r--r--drivers/sbus/char/rtc.c22
-rw-r--r--drivers/scsi/53c7xx.c6
-rw-r--r--drivers/scsi/53c7xx.h2
-rw-r--r--drivers/scsi/Kconfig31
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/NCR53C9x.c10
-rw-r--r--drivers/scsi/NCR53C9x.h6
-rw-r--r--drivers/scsi/NCR53c406a.c4
-rw-r--r--drivers/scsi/a2091.c4
-rw-r--r--drivers/scsi/a2091.h2
-rw-r--r--drivers/scsi/a3000.c4
-rw-r--r--drivers/scsi/a3000.h2
-rw-r--r--drivers/scsi/aacraid/aachba.c23
-rw-r--r--drivers/scsi/aacraid/commsup.c4
-rw-r--r--drivers/scsi/advansys.c6
-rw-r--r--drivers/scsi/advansys.h2
-rw-r--r--drivers/scsi/aha152x.c4
-rw-r--r--drivers/scsi/aha1542.c4
-rw-r--r--drivers/scsi/aha1542.h2
-rw-r--r--drivers/scsi/aha1740.c2
-rw-r--r--drivers/scsi/ahci.c73
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c37
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c39
-rw-r--r--drivers/scsi/aic7xxx_old.c18
-rw-r--r--drivers/scsi/amiga7xx.c8
-rw-r--r--drivers/scsi/amiga7xx.h2
-rw-r--r--drivers/scsi/arm/acornscsi.c6
-rw-r--r--drivers/scsi/arm/acornscsi.h2
-rw-r--r--drivers/scsi/arm/arxescsi.c8
-rw-r--r--drivers/scsi/arm/cumana_1.c2
-rw-r--r--drivers/scsi/arm/cumana_2.c8
-rw-r--r--drivers/scsi/arm/ecoscsi.c2
-rw-r--r--drivers/scsi/arm/eesox.c8
-rw-r--r--drivers/scsi/arm/fas216.c10
-rw-r--r--drivers/scsi/arm/fas216.h8
-rw-r--r--drivers/scsi/arm/oak.c2
-rw-r--r--drivers/scsi/arm/powertec.c6
-rw-r--r--drivers/scsi/arm/scsi.h8
-rw-r--r--drivers/scsi/ata_piix.c4
-rw-r--r--drivers/scsi/atari_NCR5380.c2
-rw-r--r--drivers/scsi/atari_scsi.c4
-rw-r--r--drivers/scsi/atari_scsi.h2
-rw-r--r--drivers/scsi/blz1230.c4
-rw-r--r--drivers/scsi/blz2060.c4
-rw-r--r--drivers/scsi/bvme6000.c4
-rw-r--r--drivers/scsi/bvme6000.h2
-rw-r--r--drivers/scsi/cyberstorm.c4
-rw-r--r--drivers/scsi/cyberstormII.c4
-rw-r--r--drivers/scsi/dec_esp.c2
-rw-r--r--drivers/scsi/dpti.h2
-rw-r--r--drivers/scsi/dtc.c6
-rw-r--r--drivers/scsi/dtc.h2
-rw-r--r--drivers/scsi/fastlane.c4
-rw-r--r--drivers/scsi/fcal.c8
-rw-r--r--drivers/scsi/fcal.h4
-rw-r--r--drivers/scsi/fd_mcs.c4
-rw-r--r--drivers/scsi/g_NCR5380.c6
-rw-r--r--drivers/scsi/g_NCR5380.h2
-rw-r--r--drivers/scsi/gdth.c12
-rw-r--r--drivers/scsi/gdth.h4
-rw-r--r--drivers/scsi/gdth_proc.c10
-rw-r--r--drivers/scsi/gvp11.c4
-rw-r--r--drivers/scsi/gvp11.h2
-rw-r--r--drivers/scsi/ibmmca.c8
-rw-r--r--drivers/scsi/ibmmca.h2
-rw-r--r--drivers/scsi/ide-scsi.c2
-rw-r--r--drivers/scsi/in2000.c4
-rw-r--r--drivers/scsi/in2000.h2
-rw-r--r--drivers/scsi/ipr.c904
-rw-r--r--drivers/scsi/ipr.h243
-rw-r--r--drivers/scsi/ips.c150
-rw-r--r--drivers/scsi/ips.h4
-rw-r--r--drivers/scsi/jazz_esp.c4
-rw-r--r--drivers/scsi/libata-core.c107
-rw-r--r--drivers/scsi/libata-scsi.c125
-rw-r--r--drivers/scsi/libata.h4
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c1
-rw-r--r--drivers/scsi/mac_esp.c4
-rw-r--r--drivers/scsi/mac_scsi.c6
-rw-r--r--drivers/scsi/mca_53c9x.c4
-rw-r--r--drivers/scsi/megaraid.c34
-rw-r--r--drivers/scsi/megaraid.h10
-rw-r--r--drivers/scsi/megaraid/mega_common.h2
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c81
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c5
-rw-r--r--drivers/scsi/mvme147.c4
-rw-r--r--drivers/scsi/mvme147.h2
-rw-r--r--drivers/scsi/mvme16x.c4
-rw-r--r--drivers/scsi/mvme16x.h2
-rw-r--r--drivers/scsi/nsp32.c6
-rw-r--r--drivers/scsi/oktagon_esp.c4
-rw-r--r--drivers/scsi/pas16.c6
-rw-r--r--drivers/scsi/pas16.h2
-rw-r--r--drivers/scsi/pci2000.h2
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c8
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.h6
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c4
-rw-r--r--drivers/scsi/pdc_adma.c2
-rw-r--r--drivers/scsi/pluto.c8
-rw-r--r--drivers/scsi/pluto.h4
-rw-r--r--drivers/scsi/psi240i.c4
-rw-r--r--drivers/scsi/qla1280.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c28
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c5
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h4
-rw-r--r--drivers/scsi/qlogicfas.c6
-rw-r--r--drivers/scsi/qlogicfc.c4
-rw-r--r--drivers/scsi/qlogicisp.c1934
-rw-r--r--drivers/scsi/qlogicisp_asm.c2034
-rw-r--r--drivers/scsi/raid_class.c96
-rw-r--r--drivers/scsi/sata_mv.c998
-rw-r--r--drivers/scsi/sata_nv.c2
-rw-r--r--drivers/scsi/sata_promise.c4
-rw-r--r--drivers/scsi/sata_qstor.c13
-rw-r--r--drivers/scsi/sata_sil.c2
-rw-r--r--drivers/scsi/sata_sil24.c221
-rw-r--r--drivers/scsi/sata_sis.c2
-rw-r--r--drivers/scsi/sata_svw.c4
-rw-r--r--drivers/scsi/sata_sx4.c4
-rw-r--r--drivers/scsi/sata_uli.c2
-rw-r--r--drivers/scsi/sata_via.c2
-rw-r--r--drivers/scsi/sata_vsc.c4
-rw-r--r--drivers/scsi/scsi_debug.c2
-rw-r--r--drivers/scsi/scsi_error.c157
-rw-r--r--drivers/scsi/scsi_lib.c58
-rw-r--r--drivers/scsi/scsi_priv.h1
-rw-r--r--drivers/scsi/scsi_scan.c54
-rw-r--r--drivers/scsi/scsi_sysfs.c9
-rw-r--r--drivers/scsi/scsi_typedefs.h3
-rw-r--r--drivers/scsi/sd.c22
-rw-r--r--drivers/scsi/seagate.c4
-rw-r--r--drivers/scsi/seagate.h2
-rw-r--r--drivers/scsi/sgiwd93.c6
-rw-r--r--drivers/scsi/sun3_NCR5380.c2
-rw-r--r--drivers/scsi/sun3_scsi.c6
-rw-r--r--drivers/scsi/sun3_scsi.h2
-rw-r--r--drivers/scsi/sun3_scsi_vme.c6
-rw-r--r--drivers/scsi/sun3x_esp.c4
-rw-r--r--drivers/scsi/sym53c416.c4
-rw-r--r--drivers/scsi/sym53c416.h2
-rw-r--r--drivers/scsi/t128.c6
-rw-r--r--drivers/scsi/t128.h2
-rw-r--r--drivers/scsi/u14-34f.c2
-rw-r--r--drivers/scsi/ultrastor.c8
-rw-r--r--drivers/scsi/ultrastor.h2
-rw-r--r--drivers/serial/68328serial.c7
-rw-r--r--drivers/serial/8250.c36
-rw-r--r--drivers/serial/8250_pnp.c2
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c2
-rw-r--r--drivers/serial/dz.c48
-rw-r--r--drivers/serial/imx.c31
-rw-r--r--drivers/serial/mpc52xx_uart.c36
-rw-r--r--drivers/serial/mpsc.c65
-rw-r--r--drivers/serial/mux.c19
-rw-r--r--drivers/serial/pxa.c33
-rw-r--r--drivers/serial/s3c2410.c62
-rw-r--r--drivers/serial/sa1100.c36
-rw-r--r--drivers/serial/serial_core.c84
-rw-r--r--drivers/serial/vr41xx_siu.c27
-rw-r--r--drivers/tc/zs.c150
-rw-r--r--drivers/tc/zs.h13
-rw-r--r--drivers/usb/atm/Makefile4
-rw-r--r--drivers/usb/atm/usbatm.h5
-rw-r--r--drivers/usb/core/Makefile4
-rw-r--r--drivers/usb/core/buffer.c8
-rw-r--r--drivers/usb/core/config.c5
-rw-r--r--drivers/usb/core/devio.c6
-rw-r--r--drivers/usb/core/file.c6
-rw-r--r--drivers/usb/core/hcd-pci.c7
-rw-r--r--drivers/usb/core/hcd.c5
-rw-r--r--drivers/usb/core/hub.c5
-rw-r--r--drivers/usb/core/inode.c7
-rw-r--r--drivers/usb/core/message.c10
-rw-r--r--drivers/usb/core/notify.c6
-rw-r--r--drivers/usb/core/sysfs.c7
-rw-r--r--drivers/usb/core/urb.c6
-rw-r--r--drivers/usb/core/usb.c7
-rw-r--r--drivers/usb/gadget/dummy_hcd.c80
-rw-r--r--drivers/usb/gadget/goku_udc.c1
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c31
-rw-r--r--drivers/usb/gadget/net2280.c1
-rw-r--r--drivers/usb/gadget/omap_udc.c61
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c41
-rw-r--r--drivers/usb/host/ehci-pci.c1
-rw-r--r--drivers/usb/host/isp116x-hcd.c37
-rw-r--r--drivers/usb/host/ohci-au1xxx.c31
-rw-r--r--drivers/usb/host/ohci-lh7a404.c31
-rw-r--r--drivers/usb/host/ohci-omap.c35
-rw-r--r--drivers/usb/host/ohci-pci.c1
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c21
-rw-r--r--drivers/usb/host/ohci-pxa27x.c31
-rw-r--r--drivers/usb/host/ohci-s3c2410.c21
-rw-r--r--drivers/usb/host/sl811-hcd.c61
-rw-r--r--drivers/usb/host/uhci-hcd.c1
-rw-r--r--drivers/usb/image/microtek.c37
-rw-r--r--drivers/usb/image/microtek.h2
-rw-r--r--drivers/usb/input/Makefile4
-rw-r--r--drivers/usb/input/hid-core.c12
-rw-r--r--drivers/usb/input/itmtouch.c7
-rw-r--r--drivers/usb/input/keyspan_remote.c5
-rw-r--r--drivers/usb/input/mtouchusb.c7
-rw-r--r--drivers/usb/input/pid.c2
-rw-r--r--drivers/usb/input/touchkitusb.c4
-rw-r--r--drivers/usb/input/wacom.c133
-rw-r--r--drivers/usb/misc/Makefile6
-rw-r--r--drivers/usb/misc/auerswald.c1
-rw-r--r--drivers/usb/misc/phidgetservo.c3
-rw-r--r--drivers/usb/misc/rio500.c2
-rw-r--r--drivers/usb/misc/usbled.c3
-rw-r--r--drivers/usb/misc/usbtest.c3
-rw-r--r--drivers/usb/misc/uss720.c2
-rw-r--r--drivers/usb/net/Makefile4
-rw-r--r--drivers/usb/net/asix.c3
-rw-r--r--drivers/usb/net/cdc_ether.c3
-rw-r--r--drivers/usb/net/cdc_subset.c3
-rw-r--r--drivers/usb/net/gl620a.c3
-rw-r--r--drivers/usb/net/kaweth.c13
-rw-r--r--drivers/usb/net/net1080.c3
-rw-r--r--drivers/usb/net/pegasus.c2
-rw-r--r--drivers/usb/net/plusb.c3
-rw-r--r--drivers/usb/net/rndis_host.c3
-rw-r--r--drivers/usb/net/usbnet.c3
-rw-r--r--drivers/usb/net/zaurus.c3
-rw-r--r--drivers/usb/serial/ChangeLog.history (renamed from drivers/usb/serial/ChangeLog.old)2
-rw-r--r--drivers/usb/serial/Kconfig18
-rw-r--r--drivers/usb/serial/Makefile2
-rw-r--r--drivers/usb/serial/anydata.c123
-rw-r--r--drivers/usb/serial/cp2101.c1
-rw-r--r--drivers/usb/serial/generic.c1
-rw-r--r--drivers/usb/serial/nokia_dku2.c142
-rw-r--r--drivers/usb/serial/pl2303.c6
-rw-r--r--drivers/usb/serial/pl2303.h2
-rw-r--r--drivers/usb/storage/Kconfig2
-rw-r--r--drivers/usb/storage/shuttle_usbat.c2
-rw-r--r--drivers/usb/storage/unusual_devs.h10
-rw-r--r--drivers/video/acornfb.c13
-rw-r--r--drivers/video/arcfb.c22
-rw-r--r--drivers/video/backlight/corgi_bl.c21
-rw-r--r--drivers/video/bw2.c3
-rw-r--r--drivers/video/cg14.c3
-rw-r--r--drivers/video/cg3.c3
-rw-r--r--drivers/video/cg6.c3
-rw-r--r--drivers/video/console/Kconfig7
-rw-r--r--drivers/video/console/Makefile1
-rw-r--r--drivers/video/console/fbcon.c15
-rw-r--r--drivers/video/console/fbcon.h3
-rw-r--r--drivers/video/console/fbcon_ccw.c14
-rw-r--r--drivers/video/console/fbcon_cw.c14
-rw-r--r--drivers/video/console/fbcon_ud.c22
-rw-r--r--drivers/video/console/font_rl.c4374
-rw-r--r--drivers/video/console/fonts.c4
-rw-r--r--drivers/video/dnfb.c16
-rw-r--r--drivers/video/epson1355fb.c24
-rw-r--r--drivers/video/ffb.c3
-rw-r--r--drivers/video/gbefb.c25
-rw-r--r--drivers/video/imxfb.c45
-rw-r--r--drivers/video/leo.c3
-rw-r--r--drivers/video/nvidia/nv_proto.h2
-rw-r--r--drivers/video/nvidia/nvidia.c2
-rw-r--r--drivers/video/offb.c41
-rw-r--r--drivers/video/p9100.c3
-rw-r--r--drivers/video/pxafb.c51
-rw-r--r--drivers/video/q40fb.c14
-rw-r--r--drivers/video/s1d13xxxfb.c49
-rw-r--r--drivers/video/s3c2410fb.c47
-rw-r--r--drivers/video/sa1100fb.c25
-rw-r--r--drivers/video/sbuslib.c107
-rw-r--r--drivers/video/sbuslib.h2
-rw-r--r--drivers/video/sgivwfb.c22
-rw-r--r--drivers/video/tcx.c3
-rw-r--r--drivers/video/vesafb.c16
-rw-r--r--drivers/video/vfb.c22
-rw-r--r--drivers/video/w100fb.c48
509 files changed, 15496 insertions, 18515 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 6a4da417..606f873 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -28,6 +28,7 @@
#include <linux/list.h>
#include <linux/sched.h>
#include <linux/pm.h>
+#include <linux/pm_legacy.h>
#include <linux/device.h>
#include <linux/proc_fs.h>
#ifdef CONFIG_X86
@@ -754,7 +755,7 @@ static int __init acpi_init(void)
result = acpi_bus_init();
if (!result) {
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
if (!PM_IS_ACTIVE())
pm_active = 1;
else {
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 3937adf..aa99371 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -203,6 +203,7 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL);
return find.handle;
}
+EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
/* Get device's handler per its address under its parent */
struct acpi_find_child {
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 573b6a97..70d8a6e 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -514,8 +514,6 @@ static int acpi_processor_set_power_policy(struct acpi_processor *pr)
static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
{
- int i;
-
ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_fadt");
if (!pr)
@@ -524,8 +522,7 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
if (!pr->pblk)
return_VALUE(-ENODEV);
- for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
- memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+ memset(pr->power.states, 0, sizeof(pr->power.states));
/* if info is obtained from pblk/fadt, type equals state */
pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
@@ -555,13 +552,9 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr)
{
- int i;
-
ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1");
- for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
- memset(&(pr->power.states[i]), 0,
- sizeof(struct acpi_processor_cx));
+ memset(pr->power.states, 0, sizeof(pr->power.states));
/* if info is obtained from pblk/fadt, type equals state */
pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
@@ -873,7 +866,8 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
if (pr->power.states[i].valid) {
pr->power.count = i;
- pr->flags.power = 1;
+ if (pr->power.states[i].type >= ACPI_STATE_C2)
+ pr->flags.power = 1;
}
}
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index 0cded04..821c81e 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -1511,8 +1511,8 @@ static inline short setup_idle_tx_channel (hrz_dev * dev, hrz_vcc * vcc) {
// a.k.a. prepare the channel and remember that we have done so.
tx_ch_desc * tx_desc = &memmap->tx_descs[tx_channel];
- u16 rd_ptr;
- u16 wr_ptr;
+ u32 rd_ptr;
+ u32 wr_ptr;
u16 channel = vcc->channel;
unsigned long flags;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 98f6c02..59dacb6 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -526,18 +526,23 @@ request_firmware_work_func(void *arg)
{
struct firmware_work *fw_work = arg;
const struct firmware *fw;
+ int ret;
if (!arg) {
WARN_ON(1);
return 0;
}
daemonize("%s/%s", "firmware", fw_work->name);
- _request_firmware(&fw, fw_work->name, fw_work->device,
+ ret = _request_firmware(&fw, fw_work->name, fw_work->device,
fw_work->hotplug);
- fw_work->cont(fw, fw_work->context);
- release_firmware(fw);
+ if (ret < 0)
+ fw_work->cont(NULL, fw_work->context);
+ else {
+ fw_work->cont(fw, fw_work->context);
+ release_firmware(fw);
+ }
module_put(fw_work->module);
kfree(fw_work);
- return 0;
+ return ret;
}
/**
@@ -586,6 +591,8 @@ request_firmware_nowait(
if (ret < 0) {
fw_work->cont(NULL, fw_work->context);
+ module_put(fw_work->module);
+ kfree(fw_work);
return ret;
}
return 0;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 6d4736e..8827daf 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -20,6 +20,8 @@
#include "base.h"
+#define to_platform_driver(drv) (container_of((drv), struct platform_driver, driver))
+
struct device platform_bus = {
.bus_id = "platform",
};
@@ -354,6 +356,77 @@ error:
return ERR_PTR(retval);
}
+static int platform_drv_probe(struct device *_dev)
+{
+ struct platform_driver *drv = to_platform_driver(_dev->driver);
+ struct platform_device *dev = to_platform_device(_dev);
+
+ return drv->probe(dev);
+}
+
+static int platform_drv_remove(struct device *_dev)
+{
+ struct platform_driver *drv = to_platform_driver(_dev->driver);
+ struct platform_device *dev = to_platform_device(_dev);
+
+ return drv->remove(dev);
+}
+
+static void platform_drv_shutdown(struct device *_dev)
+{
+ struct platform_driver *drv = to_platform_driver(_dev->driver);
+ struct platform_device *dev = to_platform_device(_dev);
+
+ drv->shutdown(dev);
+}
+
+static int platform_drv_suspend(struct device *_dev, pm_message_t state)
+{
+ struct platform_driver *drv = to_platform_driver(_dev->driver);
+ struct platform_device *dev = to_platform_device(_dev);
+
+ return drv->suspend(dev, state);
+}
+
+static int platform_drv_resume(struct device *_dev)
+{
+ struct platform_driver *drv = to_platform_driver(_dev->driver);
+ struct platform_device *dev = to_platform_device(_dev);
+
+ return drv->resume(dev);
+}
+
+/**
+ * platform_driver_register
+ * @drv: platform driver structure
+ */
+int platform_driver_register(struct platform_driver *drv)
+{
+ drv->driver.bus = &platform_bus_type;
+ if (drv->probe)
+ drv->driver.probe = platform_drv_probe;
+ if (drv->remove)
+ drv->driver.remove = platform_drv_remove;
+ if (drv->shutdown)
+ drv->driver.shutdown = platform_drv_shutdown;
+ if (drv->suspend)
+ drv->driver.suspend = platform_drv_suspend;
+ if (drv->resume)
+ drv->driver.resume = platform_drv_resume;
+ return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(platform_driver_register);
+
+/**
+ * platform_driver_unregister
+ * @drv: platform driver structure
+ */
+void platform_driver_unregister(struct platform_driver *drv)
+{
+ driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(platform_driver_unregister);
+
/**
* platform_match - bind platform device to platform driver.
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
index 0e1f34f..5d2d649 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -58,7 +58,6 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <scsi/scsi.h> /* for SCSI_IOCTL_GET_IDLUN */
-typedef void Scsi_Device; /* hack to avoid including scsi.h */
#include <scsi/scsi_ioctl.h>
#include <linux/hdreg.h> /* for HDIO_GETGEO */
#include <linux/blkpg.h>
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index a97c80b..a9e33db 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -148,6 +148,7 @@ static struct board_type products[] = {
static ctlr_info_t *hba[MAX_CTLR];
static void do_cciss_request(request_queue_t *q);
+static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs);
static int cciss_open(struct inode *inode, struct file *filep);
static int cciss_release(struct inode *inode, struct file *filep);
static int cciss_ioctl(struct inode *inode, struct file *filep,
@@ -1016,10 +1017,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
status = -ENOMEM;
goto cleanup1;
}
- if (ioc->Request.Type.Direction == XFER_WRITE &&
- copy_from_user(buff[sg_used], data_ptr, sz)) {
+ if (ioc->Request.Type.Direction == XFER_WRITE) {
+ if (copy_from_user(buff[sg_used], data_ptr, sz)) {
status = -ENOMEM;
- goto cleanup1;
+ goto cleanup1;
+ }
} else {
memset(buff[sg_used], 0, sz);
}
@@ -1137,8 +1139,15 @@ static int revalidate_allvol(ctlr_info_t *host)
for(i=0; i< NWD; i++) {
struct gendisk *disk = host->gendisk[i];
- if (disk->flags & GENHD_FL_UP)
- del_gendisk(disk);
+ if (disk) {
+ request_queue_t *q = disk->queue;
+
+ if (disk->flags & GENHD_FL_UP)
+ del_gendisk(disk);
+ if (q)
+ blk_cleanup_queue(q);
+ put_disk(disk);
+ }
}
/*
@@ -1452,10 +1461,13 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
* allows us to delete disk zero but keep the controller registered.
*/
if (h->gendisk[0] != disk){
- if (disk->flags & GENHD_FL_UP){
- blk_cleanup_queue(disk->queue);
- del_gendisk(disk);
- drv->queue = NULL;
+ if (disk) {
+ request_queue_t *q = disk->queue;
+ if (disk->flags & GENHD_FL_UP)
+ del_gendisk(disk);
+ if (q)
+ blk_cleanup_queue(q);
+ put_disk(disk);
}
}
@@ -1583,6 +1595,24 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
}
} else if (cmd_type == TYPE_MSG) {
switch (cmd) {
+ case 0: /* ABORT message */
+ c->Request.CDBLen = 12;
+ c->Request.Type.Attribute = ATTR_SIMPLE;
+ c->Request.Type.Direction = XFER_WRITE;
+ c->Request.Timeout = 0;
+ c->Request.CDB[0] = cmd; /* abort */
+ c->Request.CDB[1] = 0; /* abort a command */
+ /* buff contains the tag of the command to abort */
+ memcpy(&c->Request.CDB[4], buff, 8);
+ break;
+ case 1: /* RESET message */
+ c->Request.CDBLen = 12;
+ c->Request.Type.Attribute = ATTR_SIMPLE;
+ c->Request.Type.Direction = XFER_WRITE;
+ c->Request.Timeout = 0;
+ memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
+ c->Request.CDB[0] = cmd; /* reset */
+ c->Request.CDB[1] = 0x04; /* reset a LUN */
case 3: /* No-Op message */
c->Request.CDBLen = 1;
c->Request.Type.Attribute = ATTR_SIMPLE;
@@ -1869,6 +1899,52 @@ static unsigned long pollcomplete(int ctlr)
/* Invalid address to tell caller we ran out of time */
return 1;
}
+
+static int add_sendcmd_reject(__u8 cmd, int ctlr, unsigned long complete)
+{
+ /* We get in here if sendcmd() is polling for completions
+ and gets some command back that it wasn't expecting --
+ something other than that which it just sent down.
+ Ordinarily, that shouldn't happen, but it can happen when
+ the scsi tape stuff gets into error handling mode, and
+ starts using sendcmd() to try to abort commands and
+ reset tape drives. In that case, sendcmd may pick up
+ completions of commands that were sent to logical drives
+ through the block i/o system, or cciss ioctls completing, etc.
+ In that case, we need to save those completions for later
+ processing by the interrupt handler.
+ */
+
+#ifdef CONFIG_CISS_SCSI_TAPE
+ struct sendcmd_reject_list *srl = &hba[ctlr]->scsi_rejects;
+
+ /* If it's not the scsi tape stuff doing error handling, (abort */
+ /* or reset) then we don't expect anything weird. */
+ if (cmd != CCISS_RESET_MSG && cmd != CCISS_ABORT_MSG) {
+#endif
+ printk( KERN_WARNING "cciss cciss%d: SendCmd "
+ "Invalid command list address returned! (%lx)\n",
+ ctlr, complete);
+ /* not much we can do. */
+#ifdef CONFIG_CISS_SCSI_TAPE
+ return 1;
+ }
+
+ /* We've sent down an abort or reset, but something else
+ has completed */
+ if (srl->ncompletions >= (NR_CMDS + 2)) {
+ /* Uh oh. No room to save it for later... */
+ printk(KERN_WARNING "cciss%d: Sendcmd: Invalid command addr, "
+ "reject list overflow, command lost!\n", ctlr);
+ return 1;
+ }
+ /* Save it for later */
+ srl->complete[srl->ncompletions] = complete;
+ srl->ncompletions++;
+#endif
+ return 0;
+}
+
/*
* Send a command to the controller, and wait for it to complete.
* Only used at init time.
@@ -1891,7 +1967,7 @@ static int sendcmd(
unsigned long complete;
ctlr_info_t *info_p= hba[ctlr];
u64bit buff_dma_handle;
- int status;
+ int status, done = 0;
if ((c = cmd_alloc(info_p, 1)) == NULL) {
printk(KERN_WARNING "cciss: unable to get memory");
@@ -1913,7 +1989,9 @@ resend_cmd1:
info_p->access.set_intr_mask(info_p, CCISS_INTR_OFF);
/* Make sure there is room in the command FIFO */
- /* Actually it should be completely empty at this time. */
+ /* Actually it should be completely empty at this time */
+ /* unless we are in here doing error handling for the scsi */
+ /* tape side of the driver. */
for (i = 200000; i > 0; i--)
{
/* if fifo isn't full go */
@@ -1930,13 +2008,25 @@ resend_cmd1:
* Send the cmd
*/
info_p->access.submit_command(info_p, c);
- complete = pollcomplete(ctlr);
+ done = 0;
+ do {
+ complete = pollcomplete(ctlr);
#ifdef CCISS_DEBUG
- printk(KERN_DEBUG "cciss: command completed\n");
+ printk(KERN_DEBUG "cciss: command completed\n");
#endif /* CCISS_DEBUG */
- if (complete != 1) {
+ if (complete == 1) {
+ printk( KERN_WARNING
+ "cciss cciss%d: SendCmd Timeout out, "
+ "No command list address returned!\n",
+ ctlr);
+ status = IO_ERROR;
+ done = 1;
+ break;
+ }
+
+ /* This will need to change for direct lookup completions */
if ( (complete & CISS_ERROR_BIT)
&& (complete & ~CISS_ERROR_BIT) == c->busaddr)
{
@@ -1976,6 +2066,10 @@ resend_cmd1:
status = IO_ERROR;
goto cleanup1;
}
+ } else if (c->err_info->CommandStatus == CMD_UNABORTABLE) {
+ printk(KERN_WARNING "cciss%d: command could not be aborted.\n", ctlr);
+ status = IO_ERROR;
+ goto cleanup1;
}
printk(KERN_WARNING "ciss ciss%d: sendcmd"
" Error %x \n", ctlr,
@@ -1990,20 +2084,15 @@ resend_cmd1:
goto cleanup1;
}
}
+ /* This will need changing for direct lookup completions */
if (complete != c->busaddr) {
- printk( KERN_WARNING "cciss cciss%d: SendCmd "
- "Invalid command list address returned! (%lx)\n",
- ctlr, complete);
- status = IO_ERROR;
- goto cleanup1;
- }
- } else {
- printk( KERN_WARNING
- "cciss cciss%d: SendCmd Timeout out, "
- "No command list address returned!\n",
- ctlr);
- status = IO_ERROR;
- }
+ if (add_sendcmd_reject(cmd, ctlr, complete) != 0) {
+ BUG(); /* we are pretty much hosed if we get here. */
+ }
+ continue;
+ } else
+ done = 1;
+ } while (!done);
cleanup1:
/* unlock the data buffer from DMA */
@@ -2011,6 +2100,11 @@ cleanup1:
buff_dma_handle.val32.upper = c->SG[0].Addr.upper;
pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val,
c->SG[0].Len, PCI_DMA_BIDIRECTIONAL);
+#ifdef CONFIG_CISS_SCSI_TAPE
+ /* if we saved some commands for later, process them now. */
+ if (info_p->scsi_rejects.ncompletions > 0)
+ do_cciss_intr(0, info_p, NULL);
+#endif
cmd_free(info_p, c, 1);
return (status);
}
@@ -2335,6 +2429,48 @@ startio:
start_io(h);
}
+static inline unsigned long get_next_completion(ctlr_info_t *h)
+{
+#ifdef CONFIG_CISS_SCSI_TAPE
+ /* Any rejects from sendcmd() lying around? Process them first */
+ if (h->scsi_rejects.ncompletions == 0)
+ return h->access.command_completed(h);
+ else {
+ struct sendcmd_reject_list *srl;
+ int n;
+ srl = &h->scsi_rejects;
+ n = --srl->ncompletions;
+ /* printk("cciss%d: processing saved reject\n", h->ctlr); */
+ printk("p");
+ return srl->complete[n];
+ }
+#else
+ return h->access.command_completed(h);
+#endif
+}
+
+static inline int interrupt_pending(ctlr_info_t *h)
+{
+#ifdef CONFIG_CISS_SCSI_TAPE
+ return ( h->access.intr_pending(h)
+ || (h->scsi_rejects.ncompletions > 0));
+#else
+ return h->access.intr_pending(h);
+#endif
+}
+
+static inline long interrupt_not_for_us(ctlr_info_t *h)
+{
+#ifdef CONFIG_CISS_SCSI_TAPE
+ return (((h->access.intr_pending(h) == 0) ||
+ (h->interrupts_enabled == 0))
+ && (h->scsi_rejects.ncompletions == 0));
+#else
+ return (((h->access.intr_pending(h) == 0) ||
+ (h->interrupts_enabled == 0)));
+#endif
+}
+
static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
{
ctlr_info_t *h = dev_id;
@@ -2344,19 +2480,15 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
int j;
int start_queue = h->next_to_run;
- /* Is this interrupt for us? */
- if (( h->access.intr_pending(h) == 0) || (h->interrupts_enabled == 0))
+ if (interrupt_not_for_us(h))
return IRQ_NONE;
-
/*
* If there are completed commands in the completion queue,
* we had better do something about it.
*/
spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
- while( h->access.intr_pending(h))
- {
- while((a = h->access.command_completed(h)) != FIFO_EMPTY)
- {
+ while (interrupt_pending(h)) {
+ while((a = get_next_completion(h)) != FIFO_EMPTY) {
a1 = a;
if ((a & 0x04)) {
a2 = (a >> 3);
@@ -2963,7 +3095,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
printk( KERN_ERR "cciss: out of memory");
goto clean4;
}
-
+#ifdef CONFIG_CISS_SCSI_TAPE
+ hba[i]->scsi_rejects.complete =
+ kmalloc(sizeof(hba[i]->scsi_rejects.complete[0]) *
+ (NR_CMDS + 5), GFP_KERNEL);
+ if (hba[i]->scsi_rejects.complete == NULL) {
+ printk( KERN_ERR "cciss: out of memory");
+ goto clean4;
+ }
+#endif
spin_lock_init(&hba[i]->lock);
/* Initialize the pdev driver private data.
@@ -3031,6 +3171,10 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
return(1);
clean4:
+#ifdef CONFIG_CISS_SCSI_TAPE
+ if(hba[i]->scsi_rejects.complete)
+ kfree(hba[i]->scsi_rejects.complete);
+#endif
kfree(hba[i]->cmd_pool_bits);
if(hba[i]->cmd_pool)
pci_free_consistent(hba[i]->pdev,
@@ -3092,9 +3236,14 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
/* remove it from the disk list */
for (j = 0; j < NWD; j++) {
struct gendisk *disk = hba[i]->gendisk[j];
- if (disk->flags & GENHD_FL_UP) {
- del_gendisk(disk);
- blk_cleanup_queue(disk->queue);
+ if (disk) {
+ request_queue_t *q = disk->queue;
+
+ if (disk->flags & GENHD_FL_UP)
+ del_gendisk(disk);
+ if (q)
+ blk_cleanup_queue(q);
+ put_disk(disk);
}
}
@@ -3103,6 +3252,9 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct),
hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle);
kfree(hba[i]->cmd_pool_bits);
+#ifdef CONFIG_CISS_SCSI_TAPE
+ kfree(hba[i]->scsi_rejects.complete);
+#endif
release_io_mem(hba[i]);
free_hba(i);
}
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index ef277ba..3b0858c 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -44,6 +44,14 @@ typedef struct _drive_info_struct
*/
} drive_info_struct;
+#ifdef CONFIG_CISS_SCSI_TAPE
+
+struct sendcmd_reject_list {
+ int ncompletions;
+ unsigned long *complete; /* array of NR_CMDS tags */
+};
+
+#endif
struct ctlr_info
{
int ctlr;
@@ -100,6 +108,9 @@ struct ctlr_info
struct gendisk *gendisk[NWD];
#ifdef CONFIG_CISS_SCSI_TAPE
void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
+ /* list of block side commands the scsi error handling sucked up */
+ /* and saved for later processing */
+ struct sendcmd_reject_list scsi_rejects;
#endif
unsigned char alive;
};
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index ec27976..2942d32 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -42,6 +42,9 @@
#include "cciss_scsi.h"
+#define CCISS_ABORT_MSG 0x00
+#define CCISS_RESET_MSG 0x01
+
/* some prototypes... */
static int sendcmd(
__u8 cmd,
@@ -67,6 +70,8 @@ static int cciss_scsi_proc_info(
static int cciss_scsi_queue_command (struct scsi_cmnd *cmd,
void (* done)(struct scsi_cmnd *));
+static int cciss_eh_device_reset_handler(struct scsi_cmnd *);
+static int cciss_eh_abort_handler(struct scsi_cmnd *);
static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR] = {
{ .name = "cciss0", .ndevices = 0 },
@@ -90,6 +95,9 @@ static struct scsi_host_template cciss_driver_template = {
.sg_tablesize = MAXSGENTRIES,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
+ /* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */
+ .eh_device_reset_handler= cciss_eh_device_reset_handler,
+ .eh_abort_handler = cciss_eh_abort_handler,
};
#pragma pack(1)
@@ -1448,6 +1456,78 @@ cciss_proc_tape_report(int ctlr, unsigned char *buffer, off_t *pos, off_t *len)
*pos += size; *len += size;
}
+/* Need at least one of these error handlers to keep ../scsi/hosts.c from
+ * complaining. Doing a host- or bus-reset can't do anything good here.
+ * Despite what it might say in scsi_error.c, there may well be commands
+ * on the controller, as the cciss driver registers twice, once as a block
+ * device for the logical drives, and once as a scsi device, for any tape
+ * drives. So we know there are no commands out on the tape drives, but we
+ * don't know there are no commands on the controller, and it is likely
+ * that there probably are, as the cciss block device is most commonly used
+ * as a boot device (embedded controller on HP/Compaq systems.)
+*/
+
+static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
+{
+ int rc;
+ CommandList_struct *cmd_in_trouble;
+ ctlr_info_t **c;
+ int ctlr;
+
+ /* find the controller to which the command to be aborted was sent */
+ c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];
+ if (c == NULL) /* paranoia */
+ return FAILED;
+ ctlr = (*c)->ctlr;
+ printk(KERN_WARNING "cciss%d: resetting tape drive or medium changer.\n", ctlr);
+
+ /* find the command that's giving us trouble */
+ cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble;
+ if (cmd_in_trouble == NULL) { /* paranoia */
+ return FAILED;
+ }
+ /* send a reset to the SCSI LUN which the command was sent to */
+ rc = sendcmd(CCISS_RESET_MSG, ctlr, NULL, 0, 2, 0, 0,
+ (unsigned char *) &cmd_in_trouble->Header.LUN.LunAddrBytes[0],
+ TYPE_MSG);
+ /* sendcmd turned off interrputs on the board, turn 'em back on. */
+ (*c)->access.set_intr_mask(*c, CCISS_INTR_ON);
+ if (rc == 0)
+ return SUCCESS;
+ printk(KERN_WARNING "cciss%d: resetting device failed.\n", ctlr);
+ return FAILED;
+}
+
+static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)
+{
+ int rc;
+ CommandList_struct *cmd_to_abort;
+ ctlr_info_t **c;
+ int ctlr;
+
+ /* find the controller to which the command to be aborted was sent */
+ c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];
+ if (c == NULL) /* paranoia */
+ return FAILED;
+ ctlr = (*c)->ctlr;
+ printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", ctlr);
+
+ /* find the command to be aborted */
+ cmd_to_abort = (CommandList_struct *) scsicmd->host_scribble;
+ if (cmd_to_abort == NULL) /* paranoia */
+ return FAILED;
+ rc = sendcmd(CCISS_ABORT_MSG, ctlr, &cmd_to_abort->Header.Tag,
+ 0, 2, 0, 0,
+ (unsigned char *) &cmd_to_abort->Header.LUN.LunAddrBytes[0],
+ TYPE_MSG);
+ /* sendcmd turned off interrputs on the board, turn 'em back on. */
+ (*c)->access.set_intr_mask(*c, CCISS_INTR_ON);
+ if (rc == 0)
+ return SUCCESS;
+ return FAILED;
+
+}
+
#else /* no CONFIG_CISS_SCSI_TAPE */
/* If no tape support, then these become defined out of existence */
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 28002de..13b8a9b 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -98,6 +98,10 @@
*/
/*
+ * 1998/1/21 -- Richard Gooch <rgooch@atnf.csiro.au> -- devfs support
+ */
+
+/*
* 1998/05/07 -- Russell King -- More portability cleanups; moved definition of
* interrupt and dma channel to asm/floppy.h. Cleaned up some formatting &
* use of '0' for NULL.
@@ -158,10 +162,6 @@ static int print_unex = 1;
#define FDPATCHES
#include <linux/fdreg.h>
-/*
- * 1998/1/21 -- Richard Gooch <rgooch@atnf.csiro.au> -- devfs support
- */
-
#include <linux/fd.h>
#include <linux/hdreg.h>
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 59e5982..c0233ef 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1188,7 +1188,7 @@ static void pkt_count_states(struct pktcdvd_device *pd, int *states)
struct packet_data *pkt;
int i;
- for (i = 0; i <= PACKET_NUM_STATES; i++)
+ for (i = 0; i < PACKET_NUM_STATES; i++)
states[i] = 0;
spin_lock(&pd->cdrw.active_list_lock);
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index fdf4370..970f70d 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -735,7 +735,7 @@ config SGI_IP27_RTC
config GEN_RTC
tristate "Generic /dev/rtc emulation"
- depends on RTC!=y && !IA64 && !ARM && !PPC64 && !M32R && !SPARC32 && !SPARC64
+ depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC32 && !SPARC64
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index ba54b58..b02fc22 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -389,7 +389,6 @@ static struct pci_device_id agp_ali_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_ali_pci_table);
static struct pci_driver agp_ali_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-ali",
.id_table = agp_ali_pci_table,
.probe = agp_ali_probe,
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 40fcd88b2..1f77665 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -515,7 +515,6 @@ static struct pci_device_id agp_amdk7_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table);
static struct pci_driver agp_amdk7_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-amdk7",
.id_table = agp_amdk7_pci_table,
.probe = agp_amdk7_probe,
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 8f748fd..7658978 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -57,9 +57,8 @@ static int nr_garts;
static struct pci_dev * hammers[MAX_HAMMER_GARTS];
static struct resource *aperture_resource;
-static int __initdata agp_try_unsupported;
+static int __initdata agp_try_unsupported = 1;
-static int gart_iterator;
#define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++)
static void flush_amd64_tlb(struct pci_dev *dev)
@@ -73,6 +72,7 @@ static void flush_amd64_tlb(struct pci_dev *dev)
static void amd64_tlbflush(struct agp_memory *temp)
{
+ int gart_iterator;
for_each_nb()
flush_amd64_tlb(hammers[gart_iterator]);
}
@@ -222,6 +222,7 @@ static struct aper_size_info_32 amd_8151_sizes[7] =
static int amd_8151_configure(void)
{
unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real);
+ int gart_iterator;
/* Configure AGP regs in each x86-64 host bridge. */
for_each_nb() {
@@ -235,7 +236,7 @@ static int amd_8151_configure(void)
static void amd64_cleanup(void)
{
u32 tmp;
-
+ int gart_iterator;
for_each_nb() {
/* disable gart translation */
pci_read_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, &tmp);
@@ -697,13 +698,22 @@ static struct pci_device_id agp_amd64_pci_table[] = {
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
+ /* ALI/ULI M1695 */
+ {
+ .class = (PCI_CLASS_BRIDGE_HOST << 8),
+ .class_mask = ~0,
+ .vendor = PCI_VENDOR_ID_AL,
+ .device = 0x1689,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },
+
{ }
};
MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);
static struct pci_driver agp_amd64_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-amd64",
.id_table = agp_amd64_pci_table,
.probe = agp_amd64_probe,
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index fbd4155..53372a8 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -521,7 +521,6 @@ static struct pci_device_id agp_ati_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_ati_pci_table);
static struct pci_driver agp_ati_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-ati",
.id_table = agp_ati_pci_table,
.probe = agp_ati_probe,
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index d41e0a6..e7aea77 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -429,7 +429,6 @@ static struct pci_device_id agp_efficeon_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_efficeon_pci_table);
static struct pci_driver agp_efficeon_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-efficeon",
.id_table = agp_efficeon_pci_table,
.probe = agp_efficeon_probe,
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 34a4446..8ee19a4 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -622,7 +622,6 @@ static struct pci_device_id agp_intel_i460_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_intel_i460_pci_table);
static struct pci_driver agp_intel_i460_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-intel-i460",
.id_table = agp_intel_i460_pci_table,
.probe = agp_intel_i460_probe,
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 027161a..e7bed50 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -1827,7 +1827,6 @@ static struct pci_device_id agp_intel_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
static struct pci_driver agp_intel_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-intel",
.id_table = agp_intel_pci_table,
.probe = agp_intel_probe,
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 3aed0c5..80dafa3 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -398,7 +398,6 @@ static struct pci_device_id agp_nvidia_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_nvidia_pci_table);
static struct pci_driver agp_nvidia_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-nvidia",
.id_table = agp_nvidia_pci_table,
.probe = agp_nvidia_probe,
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index a701361..ebc0555 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -332,7 +332,6 @@ static struct pci_device_id agp_sis_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_sis_pci_table);
static struct pci_driver agp_sis_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-sis",
.id_table = agp_sis_pci_table,
.probe = agp_sis_probe,
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 5a5392d..3f8f7fa 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -545,7 +545,6 @@ static struct pci_device_id agp_serverworks_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_serverworks_pci_table);
static struct pci_driver agp_serverworks_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-serverworks",
.id_table = agp_serverworks_pci_table,
.probe = agp_serverworks_probe,
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 183c50a..50947e3 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -557,6 +557,10 @@ static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = {
.device_id = PCI_DEVICE_ID_APPLE_U3H_AGP,
.chipset_name = "U3H",
},
+ {
+ .device_id = PCI_DEVICE_ID_APPLE_IPID2_AGP,
+ .chipset_name = "UniNorth/Intrepid2",
+ },
};
static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
@@ -658,7 +662,6 @@ static struct pci_device_id agp_uninorth_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_uninorth_pci_table);
static struct pci_driver agp_uninorth_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-uninorth",
.id_table = agp_uninorth_pci_table,
.probe = agp_uninorth_probe,
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index 5d9a137..c847df5 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -518,7 +518,6 @@ MODULE_DEVICE_TABLE(pci, agp_via_pci_table);
static struct pci_driver agp_via_pci_driver = {
- .owner = THIS_MODULE,
.name = "agpgart-via",
.id_table = agp_via_pci_table,
.probe = agp_via_probe,
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index b7a0e4d..407708a 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -3113,7 +3113,6 @@ MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
int __init init_PCI (void)
{ /* Begin init_PCI */
memset (&epca_driver, 0, sizeof (epca_driver));
- epca_driver.owner = THIS_MODULE;
epca_driver.name = "epca";
epca_driver.id_table = epca_pci_tbl;
epca_driver.probe = epca_init_one;
diff --git a/drivers/char/ftape/lowlevel/ftape-buffer.c b/drivers/char/ftape/lowlevel/ftape-buffer.c
index 54af20c..c706ff1 100644
--- a/drivers/char/ftape/lowlevel/ftape-buffer.c
+++ b/drivers/char/ftape/lowlevel/ftape-buffer.c
@@ -33,6 +33,7 @@
#include "../lowlevel/ftape-rw.h"
#include "../lowlevel/ftape-read.h"
#include "../lowlevel/ftape-tracing.h"
+#include "../lowlevel/ftape-buffer.h"
/* DMA'able memory allocation stuff.
*/
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 6c4b3f9..f3c3aaf 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -99,7 +99,9 @@ struct smm_regs {
static inline char *i8k_get_dmi_data(int field)
{
- return dmi_get_system_info(field) ? : "N/A";
+ char *dmi_data = dmi_get_system_info(field);
+
+ return dmi_data && *dmi_data ? dmi_data : "?";
}
/*
@@ -396,7 +398,7 @@ static int i8k_proc_show(struct seq_file *seq, void *offset)
return seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
I8K_PROC_FMT,
bios_version,
- dmi_get_system_info(DMI_PRODUCT_SERIAL) ? : "N/A",
+ i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
cpu_temp,
left_fan, right_fan, left_speed, right_speed,
ac_power, fn_key);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index c1d06ba..6b302a9 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -48,7 +48,7 @@
#define PFX "IPMI message handler: "
-#define IPMI_DRIVER_VERSION "36.0"
+#define IPMI_DRIVER_VERSION "38.0"
static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
static int ipmi_init_msghandler(void);
@@ -2648,7 +2648,7 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
if (!list_empty(&intf->waiting_msgs)) {
list_add_tail(&msg->link, &intf->waiting_msgs);
- spin_unlock(&intf->waiting_msgs_lock);
+ spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
goto out;
}
spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
@@ -2657,9 +2657,9 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
if (rv > 0) {
/* Could not handle the message now, just add it to a
list to handle later. */
- spin_lock(&intf->waiting_msgs_lock);
+ spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
list_add_tail(&msg->link, &intf->waiting_msgs);
- spin_unlock(&intf->waiting_msgs_lock);
+ spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
} else if (rv == 0) {
ipmi_free_smi_msg(msg);
}
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index ea89dca..01a1f6b 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2203,7 +2203,7 @@ static void setup_xaction_handlers(struct smi_info *smi_info)
static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
{
- if (smi_info->thread != ERR_PTR(-ENOMEM))
+ if (smi_info->thread != NULL && smi_info->thread != ERR_PTR(-ENOMEM))
kthread_stop(smi_info->thread);
del_timer_sync(&smi_info->si_timer);
}
diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig
index d22bfdc..27c1179 100644
--- a/drivers/char/pcmcia/Kconfig
+++ b/drivers/char/pcmcia/Kconfig
@@ -18,5 +18,29 @@ config SYNCLINK_CS
The module will be called synclinkmp. If you want to do that, say M
here.
+config CARDMAN_4000
+ tristate "Omnikey Cardman 4000 support"
+ depends on PCMCIA
+ help
+ Enable support for the Omnikey Cardman 4000 PCMCIA Smartcard
+ reader.
+
+ This kernel driver requires additional userspace support, either
+ by the vendor-provided PC/SC ifd_handler (http://www.omnikey.com/),
+ or via the cm4000 backend of OpenCT (http://www.opensc.com/).
+
+config CARDMAN_4040
+ tristate "Omnikey CardMan 4040 support"
+ depends on PCMCIA
+ help
+ Enable support for the Omnikey CardMan 4040 PCMCIA Smartcard
+ reader.
+
+ This card is basically a USB CCID device connected to a FIFO
+ in I/O space. To use the kernel driver, you will need either the
+ PC/SC ifdhandler provided from the Omnikey homepage
+ (http://www.omnikey.com/), or a current development version of OpenCT
+ (http://www.opensc.org/).
+
endmenu
diff --git a/drivers/char/pcmcia/Makefile b/drivers/char/pcmcia/Makefile
index 1fcd4c5..0aae209 100644
--- a/drivers/char/pcmcia/Makefile
+++ b/drivers/char/pcmcia/Makefile
@@ -5,3 +5,5 @@
#
obj-$(CONFIG_SYNCLINK_CS) += synclink_cs.o
+obj-$(CONFIG_CARDMAN_4000) += cm4000_cs.o
+obj-$(CONFIG_CARDMAN_4040) += cm4040_cs.o
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
new file mode 100644
index 0000000..ef011ef
--- /dev/null
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -0,0 +1,2078 @@
+ /*
+ * A driver for the PCMCIA Smartcard Reader "Omnikey CardMan Mobile 4000"
+ *
+ * cm4000_cs.c support.linux@omnikey.com
+ *
+ * Tue Oct 23 11:32:43 GMT 2001 herp - cleaned up header files
+ * Sun Jan 20 10:11:15 MET 2002 herp - added modversion header files
+ * Thu Nov 14 16:34:11 GMT 2002 mh - added PPS functionality
+ * Tue Nov 19 16:36:27 GMT 2002 mh - added SUSPEND/RESUME functionailty
+ * Wed Jul 28 12:55:01 CEST 2004 mh - kernel 2.6 adjustments
+ *
+ * current version: 2.4.0gm4
+ *
+ * (C) 2000,2001,2002,2003,2004 Omnikey AG
+ *
+ * (C) 2005 Harald Welte <laforge@gnumonks.org>
+ * - Adhere to Kernel CodingStyle
+ * - Port to 2.6.13 "new" style PCMCIA
+ * - Check for copy_{from,to}_user return values
+ * - Use nonseekable_open()
+ *
+ * All rights reserved. Licensed under dual BSD/GPL license.
+ */
+
+/* #define PCMCIA_DEBUG 6 */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ciscode.h>
+#include <pcmcia/ds.h>
+
+#include <linux/cm4000_cs.h>
+
+/* #define ATR_CSUM */
+
+#ifdef PCMCIA_DEBUG
+#define reader_to_dev(x) (&handle_to_dev(x->link.handle))
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0600);
+#define DEBUGP(n, rdr, x, args...) do { \
+ if (pc_debug >= (n)) \
+ dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
+ __FUNCTION__ , ## args); \
+ } while (0)
+#else
+#define DEBUGP(n, rdr, x, args...)
+#endif
+static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte";
+
+#define T_1SEC (HZ)
+#define T_10MSEC msecs_to_jiffies(10)
+#define T_20MSEC msecs_to_jiffies(20)
+#define T_40MSEC msecs_to_jiffies(40)
+#define T_50MSEC msecs_to_jiffies(50)
+#define T_100MSEC msecs_to_jiffies(100)
+#define T_500MSEC msecs_to_jiffies(500)
+
+static void cm4000_detach(dev_link_t *link);
+static void cm4000_release(dev_link_t *link);
+
+static int major; /* major number we get from the kernel */
+
+/* note: the first state has to have number 0 always */
+
+#define M_FETCH_ATR 0
+#define M_TIMEOUT_WAIT 1
+#define M_READ_ATR_LEN 2
+#define M_READ_ATR 3
+#define M_ATR_PRESENT 4
+#define M_BAD_CARD 5
+#define M_CARDOFF 6
+
+#define LOCK_IO 0
+#define LOCK_MONITOR 1
+
+#define IS_AUTOPPS_ACT 6
+#define IS_PROCBYTE_PRESENT 7
+#define IS_INVREV 8
+#define IS_ANY_T0 9
+#define IS_ANY_T1 10
+#define IS_ATR_PRESENT 11
+#define IS_ATR_VALID 12
+#define IS_CMM_ABSENT 13
+#define IS_BAD_LENGTH 14
+#define IS_BAD_CSUM 15
+#define IS_BAD_CARD 16
+
+#define REG_FLAGS0(x) (x + 0)
+#define REG_FLAGS1(x) (x + 1)
+#define REG_NUM_BYTES(x) (x + 2)
+#define REG_BUF_ADDR(x) (x + 3)
+#define REG_BUF_DATA(x) (x + 4)
+#define REG_NUM_SEND(x) (x + 5)
+#define REG_BAUDRATE(x) (x + 6)
+#define REG_STOPBITS(x) (x + 7)
+
+struct cm4000_dev {
+ dev_link_t link; /* pcmcia link */
+ dev_node_t node; /* OS node (major,minor) */
+
+ unsigned char atr[MAX_ATR];
+ unsigned char rbuf[512];
+ unsigned char sbuf[512];
+
+ wait_queue_head_t devq; /* when removing cardman must not be
+ zeroed! */
+
+ wait_queue_head_t ioq; /* if IO is locked, wait on this Q */
+ wait_queue_head_t atrq; /* wait for ATR valid */
+ wait_queue_head_t readq; /* used by write to wake blk.read */
+
+ /* warning: do not move this fields.
+ * initialising to zero depends on it - see ZERO_DEV below. */
+ unsigned char atr_csum;
+ unsigned char atr_len_retry;
+ unsigned short atr_len;
+ unsigned short rlen; /* bytes avail. after write */
+ unsigned short rpos; /* latest read pos. write zeroes */
+ unsigned char procbyte; /* T=0 procedure byte */
+ unsigned char mstate; /* state of card monitor */
+ unsigned char cwarn; /* slow down warning */
+ unsigned char flags0; /* cardman IO-flags 0 */
+ unsigned char flags1; /* cardman IO-flags 1 */
+ unsigned int mdelay; /* variable monitor speeds, in jiffies */
+
+ unsigned int baudv; /* baud value for speed */
+ unsigned char ta1;
+ unsigned char proto; /* T=0, T=1, ... */
+ unsigned long flags; /* lock+flags (MONITOR,IO,ATR) * for concurrent
+ access */
+
+ unsigned char pts[4];
+
+ struct timer_list timer; /* used to keep monitor running */
+ int monitor_running;
+};
+
+#define ZERO_DEV(dev) \
+ memset(&dev->atr_csum,0, \
+ sizeof(struct cm4000_dev) - \
+ /*link*/ sizeof(dev_link_t) - \
+ /*node*/ sizeof(dev_node_t) - \
+ /*atr*/ MAX_ATR*sizeof(char) - \
+ /*rbuf*/ 512*sizeof(char) - \
+ /*sbuf*/ 512*sizeof(char) - \
+ /*queue*/ 4*sizeof(wait_queue_head_t))
+
+static dev_info_t dev_info = MODULE_NAME;
+static dev_link_t *dev_table[CM4000_MAX_DEV];
+
+/* This table doesn't use spaces after the comma between fields and thus
+ * violates CodingStyle. However, I don't really think wrapping it around will
+ * make it any clearer to read -HW */
+static unsigned char fi_di_table[10][14] = {
+/*FI 00 01 02 03 04 05 06 07 08 09 10 11 12 13 */
+/*DI */
+/* 0 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+/* 1 */ {0x01,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x91,0x11,0x11,0x11,0x11},
+/* 2 */ {0x02,0x12,0x22,0x32,0x11,0x11,0x11,0x11,0x11,0x92,0xA2,0xB2,0x11,0x11},
+/* 3 */ {0x03,0x13,0x23,0x33,0x43,0x53,0x63,0x11,0x11,0x93,0xA3,0xB3,0xC3,0xD3},
+/* 4 */ {0x04,0x14,0x24,0x34,0x44,0x54,0x64,0x11,0x11,0x94,0xA4,0xB4,0xC4,0xD4},
+/* 5 */ {0x00,0x15,0x25,0x35,0x45,0x55,0x65,0x11,0x11,0x95,0xA5,0xB5,0xC5,0xD5},
+/* 6 */ {0x06,0x16,0x26,0x36,0x46,0x56,0x66,0x11,0x11,0x96,0xA6,0xB6,0xC6,0xD6},
+/* 7 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+/* 8 */ {0x08,0x11,0x28,0x38,0x48,0x58,0x68,0x11,0x11,0x98,0xA8,0xB8,0xC8,0xD8},
+/* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9}
+};
+
+#ifndef PCMCIA_DEBUG
+#define xoutb outb
+#define xinb inb
+#else
+static inline void xoutb(unsigned char val, unsigned short port)
+{
+ if (pc_debug >= 7)
+ printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
+ outb(val, port);
+}
+static inline unsigned char xinb(unsigned short port)
+{
+ unsigned char val;
+
+ val = inb(port);
+ if (pc_debug >= 7)
+ printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
+
+ return val;
+}
+#endif
+
+#define b_0000 15
+#define b_0001 14
+#define b_0010 13
+#define b_0011 12
+#define b_0100 11
+#define b_0101 10
+#define b_0110 9
+#define b_0111 8
+#define b_1000 7
+#define b_1001 6
+#define b_1010 5
+#define b_1011 4
+#define b_1100 3
+#define b_1101 2
+#define b_1110 1
+#define b_1111 0
+
+static unsigned char irtab[16] = {
+ b_0000, b_1000, b_0100, b_1100,
+ b_0010, b_1010, b_0110, b_1110,
+ b_0001, b_1001, b_0101, b_1101,
+ b_0011, b_1011, b_0111, b_1111
+};
+
+static void str_invert_revert(unsigned char *b, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ b[i] = (irtab[b[i] & 0x0f] << 4) | irtab[b[i] >> 4];
+}
+
+static unsigned char invert_revert(unsigned char ch)
+{
+ return (irtab[ch & 0x0f] << 4) | irtab[ch >> 4];
+}
+
+#define ATRLENCK(dev,pos) \
+ if (pos>=dev->atr_len || pos>=MAX_ATR) \
+ goto return_0;
+
+static unsigned int calc_baudv(unsigned char fidi)
+{
+ unsigned int wcrcf, wbrcf, fi_rfu, di_rfu;
+
+ fi_rfu = 372;
+ di_rfu = 1;
+
+ /* FI */
+ switch ((fidi >> 4) & 0x0F) {
+ case 0x00:
+ wcrcf = 372;
+ break;
+ case 0x01:
+ wcrcf = 372;
+ break;
+ case 0x02:
+ wcrcf = 558;
+ break;
+ case 0x03:
+ wcrcf = 744;
+ break;
+ case 0x04:
+ wcrcf = 1116;
+ break;
+ case 0x05:
+ wcrcf = 1488;
+ break;
+ case 0x06:
+ wcrcf = 1860;
+ break;
+ case 0x07:
+ wcrcf = fi_rfu;
+ break;
+ case 0x08:
+ wcrcf = fi_rfu;
+ break;
+ case 0x09:
+ wcrcf = 512;
+ break;
+ case 0x0A:
+ wcrcf = 768;
+ break;
+ case 0x0B:
+ wcrcf = 1024;
+ break;
+ case 0x0C:
+ wcrcf = 1536;
+ break;
+ case 0x0D:
+ wcrcf = 2048;
+ break;
+ default:
+ wcrcf = fi_rfu;
+ break;
+ }
+
+ /* DI */
+ switch (fidi & 0x0F) {
+ case 0x00:
+ wbrcf = di_rfu;
+ break;
+ case 0x01:
+ wbrcf = 1;
+ break;
+ case 0x02:
+ wbrcf = 2;
+ break;
+ case 0x03:
+ wbrcf = 4;
+ break;
+ case 0x04:
+ wbrcf = 8;
+ break;
+ case 0x05:
+ wbrcf = 16;
+ break;
+ case 0x06:
+ wbrcf = 32;
+ break;
+ case 0x07:
+ wbrcf = di_rfu;
+ break;
+ case 0x08:
+ wbrcf = 12;
+ break;
+ case 0x09:
+ wbrcf = 20;
+ break;
+ default:
+ wbrcf = di_rfu;
+ break;
+ }
+
+ return (wcrcf / wbrcf);
+}
+
+static unsigned short io_read_num_rec_bytes(ioaddr_t iobase, unsigned short *s)
+{
+ unsigned short tmp;
+
+ tmp = *s = 0;
+ do {
+ *s = tmp;
+ tmp = inb(REG_NUM_BYTES(iobase)) |
+ (inb(REG_FLAGS0(iobase)) & 4 ? 0x100 : 0);
+ } while (tmp != *s);
+
+ return *s;
+}
+
+static int parse_atr(struct cm4000_dev *dev)
+{
+ unsigned char any_t1, any_t0;
+ unsigned char ch, ifno;
+ int ix, done;
+
+ DEBUGP(3, dev, "-> parse_atr: dev->atr_len = %i\n", dev->atr_len);
+
+ if (dev->atr_len < 3) {
+ DEBUGP(5, dev, "parse_atr: atr_len < 3\n");
+ return 0;
+ }
+
+ if (dev->atr[0] == 0x3f)
+ set_bit(IS_INVREV, &dev->flags);
+ else
+ clear_bit(IS_INVREV, &dev->flags);
+ ix = 1;
+ ifno = 1;
+ ch = dev->atr[1];
+ dev->proto = 0; /* XXX PROTO */
+ any_t1 = any_t0 = done = 0;
+ dev->ta1 = 0x11; /* defaults to 9600 baud */
+ do {
+ if (ifno == 1 && (ch & 0x10)) {
+ /* read first interface byte and TA1 is present */
+ dev->ta1 = dev->atr[2];
+ DEBUGP(5, dev, "Card says FiDi is 0x%.2x\n", dev->ta1);
+ ifno++;
+ } else if ((ifno == 2) && (ch & 0x10)) { /* TA(2) */
+ dev->ta1 = 0x11;
+ ifno++;
+ }
+
+ DEBUGP(5, dev, "Yi=%.2x\n", ch & 0xf0);
+ ix += ((ch & 0x10) >> 4) /* no of int.face chars */
+ +((ch & 0x20) >> 5)
+ + ((ch & 0x40) >> 6)
+ + ((ch & 0x80) >> 7);
+ /* ATRLENCK(dev,ix); */
+ if (ch & 0x80) { /* TDi */
+ ch = dev->atr[ix];
+ if ((ch & 0x0f)) {
+ any_t1 = 1;
+ DEBUGP(5, dev, "card is capable of T=1\n");
+ } else {
+ any_t0 = 1;
+ DEBUGP(5, dev, "card is capable of T=0\n");
+ }
+ } else
+ done = 1;
+ } while (!done);
+
+ DEBUGP(5, dev, "ix=%d noHist=%d any_t1=%d\n",
+ ix, dev->atr[1] & 15, any_t1);
+ if (ix + 1 + (dev->atr[1] & 0x0f) + any_t1 != dev->atr_len) {
+ DEBUGP(5, dev, "length error\n");
+ return 0;
+ }
+ if (any_t0)
+ set_bit(IS_ANY_T0, &dev->flags);
+
+ if (any_t1) { /* compute csum */
+ dev->atr_csum = 0;
+#ifdef ATR_CSUM
+ for (i = 1; i < dev->atr_len; i++)
+ dev->atr_csum ^= dev->atr[i];
+ if (dev->atr_csum) {
+ set_bit(IS_BAD_CSUM, &dev->flags);
+ DEBUGP(5, dev, "bad checksum\n");
+ goto return_0;
+ }
+#endif
+ if (any_t0 == 0)
+ dev->proto = 1; /* XXX PROTO */
+ set_bit(IS_ANY_T1, &dev->flags);
+ }
+
+ return 1;
+}
+
+struct card_fixup {
+ char atr[12];
+ u_int8_t atr_len;
+ u_int8_t stopbits;
+};
+
+static struct card_fixup card_fixups[] = {
+ { /* ACOS */
+ .atr = { 0x3b, 0xb3, 0x11, 0x00, 0x00, 0x41, 0x01 },
+ .atr_len = 7,
+ .stopbits = 0x03,
+ },
+ { /* Motorola */
+ .atr = {0x3b, 0x76, 0x13, 0x00, 0x00, 0x80, 0x62, 0x07,
+ 0x41, 0x81, 0x81 },
+ .atr_len = 11,
+ .stopbits = 0x04,
+ },
+};
+
+static void set_cardparameter(struct cm4000_dev *dev)
+{
+ int i;
+ ioaddr_t iobase = dev->link.io.BasePort1;
+ u_int8_t stopbits = 0x02; /* ISO default */
+
+ DEBUGP(3, dev, "-> set_cardparameter\n");
+
+ dev->flags1 = dev->flags1 | (((dev->baudv - 1) & 0x0100) >> 8);
+ xoutb(dev->flags1, REG_FLAGS1(iobase));
+ DEBUGP(5, dev, "flags1 = 0x%02x\n", dev->flags1);
+
+ /* set baudrate */
+ xoutb((unsigned char)((dev->baudv - 1) & 0xFF), REG_BAUDRATE(iobase));
+
+ DEBUGP(5, dev, "baudv = %i -> write 0x%02x\n", dev->baudv,
+ ((dev->baudv - 1) & 0xFF));
+
+ /* set stopbits */
+ for (i = 0; i < ARRAY_SIZE(card_fixups); i++) {
+ if (!memcmp(dev->atr, card_fixups[i].atr,
+ card_fixups[i].atr_len))
+ stopbits = card_fixups[i].stopbits;
+ }
+ xoutb(stopbits, REG_STOPBITS(iobase));
+
+ DEBUGP(3, dev, "<- set_cardparameter\n");
+}
+
+static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
+{
+
+ unsigned long tmp, i;
+ unsigned short num_bytes_read;
+ unsigned char pts_reply[4];
+ ssize_t rc;
+ ioaddr_t iobase = dev->link.io.BasePort1;
+
+ rc = 0;
+
+ DEBUGP(3, dev, "-> set_protocol\n");
+ DEBUGP(5, dev, "ptsreq->Protocol = 0x%.8x, ptsreq->Flags=0x%.8x, "
+ "ptsreq->pts1=0x%.2x, ptsreq->pts2=0x%.2x, "
+ "ptsreq->pts3=0x%.2x\n", (unsigned int)ptsreq->protocol,
+ (unsigned int)ptsreq->flags, ptsreq->pts1, ptsreq->pts2,
+ ptsreq->pts3);
+
+ /* Fill PTS structure */
+ dev->pts[0] = 0xff;
+ dev->pts[1] = 0x00;
+ tmp = ptsreq->protocol;
+ while ((tmp = (tmp >> 1)) > 0)
+ dev->pts[1]++;
+ dev->proto = dev->pts[1]; /* Set new protocol */
+ dev->pts[1] = (0x01 << 4) | (dev->pts[1]);
+
+ /* Correct Fi/Di according to CM4000 Fi/Di table */
+ DEBUGP(5, dev, "Ta(1) from ATR is 0x%.2x\n", dev->ta1);
+ /* set Fi/Di according to ATR TA(1) */
+ dev->pts[2] = fi_di_table[dev->ta1 & 0x0F][(dev->ta1 >> 4) & 0x0F];
+
+ /* Calculate PCK character */
+ dev->pts[3] = dev->pts[0] ^ dev->pts[1] ^ dev->pts[2];
+
+ DEBUGP(5, dev, "pts0=%.2x, pts1=%.2x, pts2=%.2x, pts3=%.2x\n",
+ dev->pts[0], dev->pts[1], dev->pts[2], dev->pts[3]);
+
+ /* check card convention */
+ if (test_bit(IS_INVREV, &dev->flags))
+ str_invert_revert(dev->pts, 4);
+
+ /* reset SM */
+ xoutb(0x80, REG_FLAGS0(iobase));
+
+ /* Enable access to the message buffer */
+ DEBUGP(5, dev, "Enable access to the messages buffer\n");
+ dev->flags1 = 0x20 /* T_Active */
+ | (test_bit(IS_INVREV, &dev->flags) ? 0x02 : 0x00) /* inv parity */
+ | ((dev->baudv >> 8) & 0x01); /* MSB-baud */
+ xoutb(dev->flags1, REG_FLAGS1(iobase));
+
+ DEBUGP(5, dev, "Enable message buffer -> flags1 = 0x%.2x\n",
+ dev->flags1);
+
+ /* write challenge to the buffer */
+ DEBUGP(5, dev, "Write challenge to buffer: ");
+ for (i = 0; i < 4; i++) {
+ xoutb(i, REG_BUF_ADDR(iobase));
+ xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */
+#ifdef PCMCIA_DEBUG
+ if (pc_debug >= 5)
+ printk("0x%.2x ", dev->pts[i]);
+ }
+ if (pc_debug >= 5)
+ printk("\n");
+#else
+ }
+#endif
+
+ /* set number of bytes to write */
+ DEBUGP(5, dev, "Set number of bytes to write\n");
+ xoutb(0x04, REG_NUM_SEND(iobase));
+
+ /* Trigger CARDMAN CONTROLLER */
+ xoutb(0x50, REG_FLAGS0(iobase));
+
+ /* Monitor progress */
+ /* wait for xmit done */
+ DEBUGP(5, dev, "Waiting for NumRecBytes getting valid\n");
+
+ for (i = 0; i < 100; i++) {
+ if (inb(REG_FLAGS0(iobase)) & 0x08) {
+ DEBUGP(5, dev, "NumRecBytes is valid\n");
+ break;
+ }
+ mdelay(10);
+ }
+ if (i == 100) {
+ DEBUGP(5, dev, "Timeout waiting for NumRecBytes getting "
+ "valid\n");
+ rc = -EIO;
+ goto exit_setprotocol;
+ }
+
+ DEBUGP(5, dev, "Reading NumRecBytes\n");
+ for (i = 0; i < 100; i++) {
+ io_read_num_rec_bytes(iobase, &num_bytes_read);
+ if (num_bytes_read >= 4) {
+ DEBUGP(2, dev, "NumRecBytes = %i\n", num_bytes_read);
+ break;
+ }
+ mdelay(10);
+ }
+
+ /* check whether it is a short PTS reply? */
+ if (num_bytes_read == 3)
+ i = 0;
+
+ if (i == 100) {
+ DEBUGP(5, dev, "Timeout reading num_bytes_read\n");
+ rc = -EIO;
+ goto exit_setprotocol;
+ }
+
+ DEBUGP(5, dev, "Reset the CARDMAN CONTROLLER\n");
+ xoutb(0x80, REG_FLAGS0(iobase));
+
+ /* Read PPS reply */
+ DEBUGP(5, dev, "Read PPS reply\n");
+ for (i = 0; i < num_bytes_read; i++) {
+ xoutb(i, REG_BUF_ADDR(iobase));
+ pts_reply[i] = inb(REG_BUF_DATA(iobase));
+ }
+
+#ifdef PCMCIA_DEBUG
+ DEBUGP(2, dev, "PTSreply: ");
+ for (i = 0; i < num_bytes_read; i++) {
+ if (pc_debug >= 5)
+ printk("0x%.2x ", pts_reply[i]);
+ }
+ printk("\n");
+#endif /* PCMCIA_DEBUG */
+
+ DEBUGP(5, dev, "Clear Tactive in Flags1\n");
+ xoutb(0x20, REG_FLAGS1(iobase));
+
+ /* Compare ptsreq and ptsreply */
+ if ((dev->pts[0] == pts_reply[0]) &&
+ (dev->pts[1] == pts_reply[1]) &&
+ (dev->pts[2] == pts_reply[2]) && (dev->pts[3] == pts_reply[3])) {
+ /* setcardparameter according to PPS */
+ dev->baudv = calc_baudv(dev->pts[2]);
+ set_cardparameter(dev);
+ } else if ((dev->pts[0] == pts_reply[0]) &&
+ ((dev->pts[1] & 0xef) == pts_reply[1]) &&
+ ((pts_reply[0] ^ pts_reply[1]) == pts_reply[2])) {
+ /* short PTS reply, set card parameter to default values */
+ dev->baudv = calc_baudv(0x11);
+ set_cardparameter(dev);
+ } else
+ rc = -EIO;
+
+exit_setprotocol:
+ DEBUGP(3, dev, "<- set_protocol\n");
+ return rc;
+}
+
+static int io_detect_cm4000(ioaddr_t iobase, struct cm4000_dev *dev)
+{
+
+ /* note: statemachine is assumed to be reset */
+ if (inb(REG_FLAGS0(iobase)) & 8) {
+ clear_bit(IS_ATR_VALID, &dev->flags);
+ set_bit(IS_CMM_ABSENT, &dev->flags);
+ return 0; /* detect CMM = 1 -> failure */
+ }
+ /* xoutb(0x40, REG_FLAGS1(iobase)); detectCMM */
+ xoutb(dev->flags1 | 0x40, REG_FLAGS1(iobase));
+ if ((inb(REG_FLAGS0(iobase)) & 8) == 0) {
+ clear_bit(IS_ATR_VALID, &dev->flags);
+ set_bit(IS_CMM_ABSENT, &dev->flags);
+ return 0; /* detect CMM=0 -> failure */
+ }
+ /* clear detectCMM again by restoring original flags1 */
+ xoutb(dev->flags1, REG_FLAGS1(iobase));
+ return 1;
+}
+
+static void terminate_monitor(struct cm4000_dev *dev)
+{
+
+ /* tell the monitor to stop and wait until
+ * it terminates.
+ */
+ DEBUGP(3, dev, "-> terminate_monitor\n");
+ wait_event_interruptible(dev->devq,
+ test_and_set_bit(LOCK_MONITOR,
+ (void *)&dev->flags));
+
+ /* now, LOCK_MONITOR has been set.
+ * allow a last cycle in the monitor.
+ * the monitor will indicate that it has
+ * finished by clearing this bit.
+ */
+ DEBUGP(5, dev, "Now allow last cycle of monitor!\n");
+ while (test_bit(LOCK_MONITOR, (void *)&dev->flags))
+ msleep(25);
+
+ DEBUGP(5, dev, "Delete timer\n");
+ del_timer_sync(&dev->timer);
+#ifdef PCMCIA_DEBUG
+ dev->monitor_running = 0;
+#endif
+
+ DEBUGP(3, dev, "<- terminate_monitor\n");
+}
+
+/*
+ * monitor the card every 50msec. as a side-effect, retrieve the
+ * atr once a card is inserted. another side-effect of retrieving the
+ * atr is that the card will be powered on, so there is no need to
+ * power on the card explictely from the application: the driver
+ * is already doing that for you.
+ */
+
+static void monitor_card(unsigned long p)
+{
+ struct cm4000_dev *dev = (struct cm4000_dev *) p;
+ ioaddr_t iobase = dev->link.io.BasePort1;
+ unsigned short s;
+ struct ptsreq ptsreq;
+ int i, atrc;
+
+ DEBUGP(7, dev, "-> monitor_card\n");
+
+ /* if someone has set the lock for us: we're done! */
+ if (test_and_set_bit(LOCK_MONITOR, &dev->flags)) {
+ DEBUGP(4, dev, "About to stop monitor\n");
+ /* no */
+ dev->rlen =
+ dev->rpos =
+ dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0;
+ dev->mstate = M_FETCH_ATR;
+ clear_bit(LOCK_MONITOR, &dev->flags);
+ /* close et al. are sleeping on devq, so wake it */
+ wake_up_interruptible(&dev->devq);
+ DEBUGP(2, dev, "<- monitor_card (we are done now)\n");
+ return;
+ }
+
+ /* try to lock io: if it is already locked, just add another timer */
+ if (test_and_set_bit(LOCK_IO, (void *)&dev->flags)) {
+ DEBUGP(4, dev, "Couldn't get IO lock\n");
+ goto return_with_timer;
+ }
+
+ /* is a card/a reader inserted at all ? */
+ dev->flags0 = xinb(REG_FLAGS0(iobase));
+ DEBUGP(7, dev, "dev->flags0 = 0x%2x\n", dev->flags0);
+ DEBUGP(7, dev, "smartcard present: %s\n",
+ dev->flags0 & 1 ? "yes" : "no");
+ DEBUGP(7, dev, "cardman present: %s\n",
+ dev->flags0 == 0xff ? "no" : "yes");
+
+ if ((dev->flags0 & 1) == 0 /* no smartcard inserted */
+ || dev->flags0 == 0xff) { /* no cardman inserted */
+ /* no */
+ dev->rlen =
+ dev->rpos =
+ dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0;
+ dev->mstate = M_FETCH_ATR;
+
+ dev->flags &= 0x000000ff; /* only keep IO and MONITOR locks */
+
+ if (dev->flags0 == 0xff) {
+ DEBUGP(4, dev, "set IS_CMM_ABSENT bit\n");
+ set_bit(IS_CMM_ABSENT, &dev->flags);
+ } else if (test_bit(IS_CMM_ABSENT, &dev->flags)) {
+ DEBUGP(4, dev, "clear IS_CMM_ABSENT bit "
+ "(card is removed)\n");
+ clear_bit(IS_CMM_ABSENT, &dev->flags);
+ }
+
+ goto release_io;
+ } else if ((dev->flags0 & 1) && test_bit(IS_CMM_ABSENT, &dev->flags)) {
+ /* cardman and card present but cardman was absent before
+ * (after suspend with inserted card) */
+ DEBUGP(4, dev, "clear IS_CMM_ABSENT bit (card is inserted)\n");
+ clear_bit(IS_CMM_ABSENT, &dev->flags);
+ }
+
+ if (test_bit(IS_ATR_VALID, &dev->flags) == 1) {
+ DEBUGP(7, dev, "believe ATR is already valid (do nothing)\n");
+ goto release_io;
+ }
+
+ switch (dev->mstate) {
+ unsigned char flags0;
+ case M_CARDOFF:
+ DEBUGP(4, dev, "M_CARDOFF\n");
+ flags0 = inb(REG_FLAGS0(iobase));
+ if (flags0 & 0x02) {
+ /* wait until Flags0 indicate power is off */
+ dev->mdelay = T_10MSEC;
+ } else {
+ /* Flags0 indicate power off and no card inserted now;
+ * Reset CARDMAN CONTROLLER */
+ xoutb(0x80, REG_FLAGS0(iobase));
+
+ /* prepare for fetching ATR again: after card off ATR
+ * is read again automatically */
+ dev->rlen =
+ dev->rpos =
+ dev->atr_csum =
+ dev->atr_len_retry = dev->cwarn = 0;
+ dev->mstate = M_FETCH_ATR;
+
+ /* minimal gap between CARDOFF and read ATR is 50msec */
+ dev->mdelay = T_50MSEC;
+ }
+ break;
+ case M_FETCH_ATR:
+ DEBUGP(4, dev, "M_FETCH_ATR\n");
+ xoutb(0x80, REG_FLAGS0(iobase));
+ DEBUGP(4, dev, "Reset BAUDV to 9600\n");
+ dev->baudv = 0x173; /* 9600 */
+ xoutb(0x02, REG_STOPBITS(iobase)); /* stopbits=2 */
+ xoutb(0x73, REG_BAUDRATE(iobase)); /* baud value */
+ xoutb(0x21, REG_FLAGS1(iobase)); /* T_Active=1, baud
+ value */
+ /* warm start vs. power on: */
+ xoutb(dev->flags0 & 2 ? 0x46 : 0x44, REG_FLAGS0(iobase));
+ dev->mdelay = T_40MSEC;
+ dev->mstate = M_TIMEOUT_WAIT;
+ break;
+ case M_TIMEOUT_WAIT:
+ DEBUGP(4, dev, "M_TIMEOUT_WAIT\n");
+ /* numRecBytes */
+ io_read_num_rec_bytes(iobase, &dev->atr_len);
+ dev->mdelay = T_10MSEC;
+ dev->mstate = M_READ_ATR_LEN;
+ break;
+ case M_READ_ATR_LEN:
+ DEBUGP(4, dev, "M_READ_ATR_LEN\n");
+ /* infinite loop possible, since there is no timeout */
+
+#define MAX_ATR_LEN_RETRY 100
+
+ if (dev->atr_len == io_read_num_rec_bytes(iobase, &s)) {
+ if (dev->atr_len_retry++ >= MAX_ATR_LEN_RETRY) { /* + XX msec */
+ dev->mdelay = T_10MSEC;
+ dev->mstate = M_READ_ATR;
+ }
+ } else {
+ dev->atr_len = s;
+ dev->atr_len_retry = 0; /* set new timeout */
+ }
+
+ DEBUGP(4, dev, "Current ATR_LEN = %i\n", dev->atr_len);
+ break;
+ case M_READ_ATR:
+ DEBUGP(4, dev, "M_READ_ATR\n");
+ xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */
+ for (i = 0; i < dev->atr_len; i++) {
+ xoutb(i, REG_BUF_ADDR(iobase));
+ dev->atr[i] = inb(REG_BUF_DATA(iobase));
+ }
+ /* Deactivate T_Active flags */
+ DEBUGP(4, dev, "Deactivate T_Active flags\n");
+ dev->flags1 = 0x01;
+ xoutb(dev->flags1, REG_FLAGS1(iobase));
+
+ /* atr is present (which doesnt mean it's valid) */
+ set_bit(IS_ATR_PRESENT, &dev->flags);
+ if (dev->atr[0] == 0x03)
+ str_invert_revert(dev->atr, dev->atr_len);
+ atrc = parse_atr(dev);
+ if (atrc == 0) { /* atr invalid */
+ dev->mdelay = 0;
+ dev->mstate = M_BAD_CARD;
+ } else {
+ dev->mdelay = T_50MSEC;
+ dev->mstate = M_ATR_PRESENT;
+ set_bit(IS_ATR_VALID, &dev->flags);
+ }
+
+ if (test_bit(IS_ATR_VALID, &dev->flags) == 1) {
+ DEBUGP(4, dev, "monitor_card: ATR valid\n");
+ /* if ta1 == 0x11, no PPS necessary (default values) */
+ /* do not do PPS with multi protocol cards */
+ if ((test_bit(IS_AUTOPPS_ACT, &dev->flags) == 0) &&
+ (dev->ta1 != 0x11) &&
+ !(test_bit(IS_ANY_T0, &dev->flags) &&
+ test_bit(IS_ANY_T1, &dev->flags))) {
+ DEBUGP(4, dev, "Perform AUTOPPS\n");
+ set_bit(IS_AUTOPPS_ACT, &dev->flags);
+ ptsreq.protocol = ptsreq.protocol =
+ (0x01 << dev->proto);
+ ptsreq.flags = 0x01;
+ ptsreq.pts1 = 0x00;
+ ptsreq.pts2 = 0x00;
+ ptsreq.pts3 = 0x00;
+ if (set_protocol(dev, &ptsreq) == 0) {
+ DEBUGP(4, dev, "AUTOPPS ret SUCC\n");
+ clear_bit(IS_AUTOPPS_ACT, &dev->flags);
+ wake_up_interruptible(&dev->atrq);
+ } else {
+ DEBUGP(4, dev, "AUTOPPS failed: "
+ "repower using defaults\n");
+ /* prepare for repowering */
+ clear_bit(IS_ATR_PRESENT, &dev->flags);
+ clear_bit(IS_ATR_VALID, &dev->flags);
+ dev->rlen =
+ dev->rpos =
+ dev->atr_csum =
+ dev->atr_len_retry = dev->cwarn = 0;
+ dev->mstate = M_FETCH_ATR;
+
+ dev->mdelay = T_50MSEC;
+ }
+ } else {
+ /* for cards which use slightly different
+ * params (extra guard time) */
+ set_cardparameter(dev);
+ if (test_bit(IS_AUTOPPS_ACT, &dev->flags) == 1)
+ DEBUGP(4, dev, "AUTOPPS already active "
+ "2nd try:use default values\n");
+ if (dev->ta1 == 0x11)
+ DEBUGP(4, dev, "No AUTOPPS necessary "
+ "TA(1)==0x11\n");
+ if (test_bit(IS_ANY_T0, &dev->flags)
+ && test_bit(IS_ANY_T1, &dev->flags))
+ DEBUGP(4, dev, "Do NOT perform AUTOPPS "
+ "with multiprotocol cards\n");
+ clear_bit(IS_AUTOPPS_ACT, &dev->flags);
+ wake_up_interruptible(&dev->atrq);
+ }
+ } else {
+ DEBUGP(4, dev, "ATR invalid\n");
+ wake_up_interruptible(&dev->atrq);
+ }
+ break;
+ case M_BAD_CARD:
+ DEBUGP(4, dev, "M_BAD_CARD\n");
+ /* slow down warning, but prompt immediately after insertion */
+ if (dev->cwarn == 0 || dev->cwarn == 10) {
+ set_bit(IS_BAD_CARD, &dev->flags);
+ printk(KERN_WARNING MODULE_NAME ": device %s: ",
+ dev->node.dev_name);
+ if (test_bit(IS_BAD_CSUM, &dev->flags)) {
+ DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
+ "be zero) failed\n", dev->atr_csum);
+ }
+#ifdef PCMCIA_DEBUG
+ else if (test_bit(IS_BAD_LENGTH, &dev->flags)) {
+ DEBUGP(4, dev, "ATR length error\n");
+ } else {
+ DEBUGP(4, dev, "card damaged or wrong way "
+ "inserted\n");
+ }
+#endif
+ dev->cwarn = 0;
+ wake_up_interruptible(&dev->atrq); /* wake open */
+ }
+ dev->cwarn++;
+ dev->mdelay = T_100MSEC;
+ dev->mstate = M_FETCH_ATR;
+ break;
+ default:
+ DEBUGP(7, dev, "Unknown action\n");
+ break; /* nothing */
+ }
+
+release_io:
+ DEBUGP(7, dev, "release_io\n");
+ clear_bit(LOCK_IO, &dev->flags);
+ wake_up_interruptible(&dev->ioq); /* whoever needs IO */
+
+return_with_timer:
+ DEBUGP(7, dev, "<- monitor_card (returns with timer)\n");
+ dev->timer.expires = jiffies + dev->mdelay;
+ add_timer(&dev->timer);
+ clear_bit(LOCK_MONITOR, &dev->flags);
+}
+
+/* Interface to userland (file_operations) */
+
+static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
+ loff_t *ppos)
+{
+ struct cm4000_dev *dev = filp->private_data;
+ ioaddr_t iobase = dev->link.io.BasePort1;
+ ssize_t rc;
+ int i, j, k;
+
+ DEBUGP(2, dev, "-> cmm_read(%s,%d)\n", current->comm, current->pid);
+
+ if (count == 0) /* according to manpage */
+ return 0;
+
+ if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */
+ test_bit(IS_CMM_ABSENT, &dev->flags))
+ return -ENODEV;
+
+ if (test_bit(IS_BAD_CSUM, &dev->flags))
+ return -EIO;
+
+ /* also see the note about this in cmm_write */
+ if (wait_event_interruptible
+ (dev->atrq,
+ ((filp->f_flags & O_NONBLOCK)
+ || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ return -ERESTARTSYS;
+ }
+
+ if (test_bit(IS_ATR_VALID, &dev->flags) == 0)
+ return -EIO;
+
+ /* this one implements blocking IO */
+ if (wait_event_interruptible
+ (dev->readq,
+ ((filp->f_flags & O_NONBLOCK) || (dev->rpos < dev->rlen)))) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ return -ERESTARTSYS;
+ }
+
+ /* lock io */
+ if (wait_event_interruptible
+ (dev->ioq,
+ ((filp->f_flags & O_NONBLOCK)
+ || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ return -ERESTARTSYS;
+ }
+
+ rc = 0;
+ dev->flags0 = inb(REG_FLAGS0(iobase));
+ if ((dev->flags0 & 1) == 0 /* no smartcard inserted */
+ || dev->flags0 == 0xff) { /* no cardman inserted */
+ clear_bit(IS_ATR_VALID, &dev->flags);
+ if (dev->flags0 & 1) {
+ set_bit(IS_CMM_ABSENT, &dev->flags);
+ rc = -ENODEV;
+ }
+ rc = -EIO;
+ goto release_io;
+ }
+
+ DEBUGP(4, dev, "begin read answer\n");
+ j = min(count, (size_t)(dev->rlen - dev->rpos));
+ k = dev->rpos;
+ if (k + j > 255)
+ j = 256 - k;
+ DEBUGP(4, dev, "read1 j=%d\n", j);
+ for (i = 0; i < j; i++) {
+ xoutb(k++, REG_BUF_ADDR(iobase));
+ dev->rbuf[i] = xinb(REG_BUF_DATA(iobase));
+ }
+ j = min(count, (size_t)(dev->rlen - dev->rpos));
+ if (k + j > 255) {
+ DEBUGP(4, dev, "read2 j=%d\n", j);
+ dev->flags1 |= 0x10; /* MSB buf addr set */
+ xoutb(dev->flags1, REG_FLAGS1(iobase));
+ for (; i < j; i++) {
+ xoutb(k++, REG_BUF_ADDR(iobase));
+ dev->rbuf[i] = xinb(REG_BUF_DATA(iobase));
+ }
+ }
+
+ if (dev->proto == 0 && count > dev->rlen - dev->rpos) {
+ DEBUGP(4, dev, "T=0 and count > buffer\n");
+ dev->rbuf[i] = dev->rbuf[i - 1];
+ dev->rbuf[i - 1] = dev->procbyte;
+ j++;
+ }
+ count = j;
+
+ dev->rpos = dev->rlen + 1;
+
+ /* Clear T1Active */
+ DEBUGP(4, dev, "Clear T1Active\n");
+ dev->flags1 &= 0xdf;
+ xoutb(dev->flags1, REG_FLAGS1(iobase));
+
+ xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */
+ /* last check before exit */
+ if (!io_detect_cm4000(iobase, dev))
+ count = -ENODEV;
+
+ if (test_bit(IS_INVREV, &dev->flags) && count > 0)
+ str_invert_revert(dev->rbuf, count);
+
+ if (copy_to_user(buf, dev->rbuf, count))
+ return -EFAULT;
+
+release_io:
+ clear_bit(LOCK_IO, &dev->flags);
+ wake_up_interruptible(&dev->ioq);
+
+ DEBUGP(2, dev, "<- cmm_read returns: rc = %Zi\n",
+ (rc < 0 ? rc : count));
+ return rc < 0 ? rc : count;
+}
+
+static ssize_t cmm_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data;
+ ioaddr_t iobase = dev->link.io.BasePort1;
+ unsigned short s;
+ unsigned char tmp;
+ unsigned char infolen;
+ unsigned char sendT0;
+ unsigned short nsend;
+ unsigned short nr;
+ ssize_t rc;
+ int i;
+
+ DEBUGP(2, dev, "-> cmm_write(%s,%d)\n", current->comm, current->pid);
+
+ if (count == 0) /* according to manpage */
+ return 0;
+
+ if (dev->proto == 0 && count < 4) {
+ /* T0 must have at least 4 bytes */
+ DEBUGP(4, dev, "T0 short write\n");
+ return -EIO;
+ }
+
+ nr = count & 0x1ff; /* max bytes to write */
+
+ sendT0 = dev->proto ? 0 : nr > 5 ? 0x08 : 0;
+
+ if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */
+ test_bit(IS_CMM_ABSENT, &dev->flags))
+ return -ENODEV;
+
+ if (test_bit(IS_BAD_CSUM, &dev->flags)) {
+ DEBUGP(4, dev, "bad csum\n");
+ return -EIO;
+ }
+
+ /*
+ * wait for atr to become valid.
+ * note: it is important to lock this code. if we dont, the monitor
+ * could be run between test_bit and the the call the sleep on the
+ * atr-queue. if *then* the monitor detects atr valid, it will wake up
+ * any process on the atr-queue, *but* since we have been interrupted,
+ * we do not yet sleep on this queue. this would result in a missed
+ * wake_up and the calling process would sleep forever (until
+ * interrupted). also, do *not* restore_flags before sleep_on, because
+ * this could result in the same situation!
+ */
+ if (wait_event_interruptible
+ (dev->atrq,
+ ((filp->f_flags & O_NONBLOCK)
+ || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ return -ERESTARTSYS;
+ }
+
+ if (test_bit(IS_ATR_VALID, &dev->flags) == 0) { /* invalid atr */
+ DEBUGP(4, dev, "invalid ATR\n");
+ return -EIO;
+ }
+
+ /* lock io */
+ if (wait_event_interruptible
+ (dev->ioq,
+ ((filp->f_flags & O_NONBLOCK)
+ || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ return -ERESTARTSYS;
+ }
+
+ if (copy_from_user(dev->sbuf, buf, ((count > 512) ? 512 : count)))
+ return -EFAULT;
+
+ rc = 0;
+ dev->flags0 = inb(REG_FLAGS0(iobase));
+ if ((dev->flags0 & 1) == 0 /* no smartcard inserted */
+ || dev->flags0 == 0xff) { /* no cardman inserted */
+ clear_bit(IS_ATR_VALID, &dev->flags);
+ if (dev->flags0 & 1) {
+ set_bit(IS_CMM_ABSENT, &dev->flags);
+ rc = -ENODEV;
+ } else {
+ DEBUGP(4, dev, "IO error\n");
+ rc = -EIO;
+ }
+ goto release_io;
+ }
+
+ xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */
+
+ if (!io_detect_cm4000(iobase, dev)) {
+ rc = -ENODEV;
+ goto release_io;
+ }
+
+ /* reflect T=0 send/read mode in flags1 */
+ dev->flags1 |= (sendT0);
+
+ set_cardparameter(dev);
+
+ /* dummy read, reset flag procedure received */
+ tmp = inb(REG_FLAGS1(iobase));
+
+ dev->flags1 = 0x20 /* T_Active */
+ | (sendT0)
+ | (test_bit(IS_INVREV, &dev->flags) ? 2 : 0)/* inverse parity */
+ | (((dev->baudv - 1) & 0x0100) >> 8); /* MSB-Baud */
+ DEBUGP(1, dev, "set dev->flags1 = 0x%.2x\n", dev->flags1);
+ xoutb(dev->flags1, REG_FLAGS1(iobase));
+
+ /* xmit data */
+ DEBUGP(4, dev, "Xmit data\n");
+ for (i = 0; i < nr; i++) {
+ if (i >= 256) {
+ dev->flags1 = 0x20 /* T_Active */
+ | (sendT0) /* SendT0 */
+ /* inverse parity: */
+ | (test_bit(IS_INVREV, &dev->flags) ? 2 : 0)
+ | (((dev->baudv - 1) & 0x0100) >> 8) /* MSB-Baud */
+ | 0x10; /* set address high */
+ DEBUGP(4, dev, "dev->flags = 0x%.2x - set address "
+ "high\n", dev->flags1);
+ xoutb(dev->flags1, REG_FLAGS1(iobase));
+ }
+ if (test_bit(IS_INVREV, &dev->flags)) {
+ DEBUGP(4, dev, "Apply inverse convention for 0x%.2x "
+ "-> 0x%.2x\n", (unsigned char)dev->sbuf[i],
+ invert_revert(dev->sbuf[i]));
+ xoutb(i, REG_BUF_ADDR(iobase));
+ xoutb(invert_revert(dev->sbuf[i]),
+ REG_BUF_DATA(iobase));
+ } else {
+ xoutb(i, REG_BUF_ADDR(iobase));
+ xoutb(dev->sbuf[i], REG_BUF_DATA(iobase));
+ }
+ }
+ DEBUGP(4, dev, "Xmit done\n");
+
+ if (dev->proto == 0) {
+ /* T=0 proto: 0 byte reply */
+ if (nr == 4) {
+ DEBUGP(4, dev, "T=0 assumes 0 byte reply\n");
+ xoutb(i, REG_BUF_ADDR(iobase));
+ if (test_bit(IS_INVREV, &dev->flags))
+ xoutb(0xff, REG_BUF_DATA(iobase));
+ else
+ xoutb(0x00, REG_BUF_DATA(iobase));
+ }
+
+ /* numSendBytes */
+ if (sendT0)
+ nsend = nr;
+ else {
+ if (nr == 4)
+ nsend = 5;
+ else {
+ nsend = 5 + (unsigned char)dev->sbuf[4];
+ if (dev->sbuf[4] == 0)
+ nsend += 0x100;
+ }
+ }
+ } else
+ nsend = nr;
+
+ /* T0: output procedure byte */
+ if (test_bit(IS_INVREV, &dev->flags)) {
+ DEBUGP(4, dev, "T=0 set Procedure byte (inverse-reverse) "
+ "0x%.2x\n", invert_revert(dev->sbuf[1]));
+ xoutb(invert_revert(dev->sbuf[1]), REG_NUM_BYTES(iobase));
+ } else {
+ DEBUGP(4, dev, "T=0 set Procedure byte 0x%.2x\n", dev->sbuf[1]);
+ xoutb(dev->sbuf[1], REG_NUM_BYTES(iobase));
+ }
+
+ DEBUGP(1, dev, "set NumSendBytes = 0x%.2x\n",
+ (unsigned char)(nsend & 0xff));
+ xoutb((unsigned char)(nsend & 0xff), REG_NUM_SEND(iobase));
+
+ DEBUGP(1, dev, "Trigger CARDMAN CONTROLLER (0x%.2x)\n",
+ 0x40 /* SM_Active */
+ | (dev->flags0 & 2 ? 0 : 4) /* power on if needed */
+ |(dev->proto ? 0x10 : 0x08) /* T=1/T=0 */
+ |(nsend & 0x100) >> 8 /* MSB numSendBytes */ );
+ xoutb(0x40 /* SM_Active */
+ | (dev->flags0 & 2 ? 0 : 4) /* power on if needed */
+ |(dev->proto ? 0x10 : 0x08) /* T=1/T=0 */
+ |(nsend & 0x100) >> 8, /* MSB numSendBytes */
+ REG_FLAGS0(iobase));
+
+ /* wait for xmit done */
+ if (dev->proto == 1) {
+ DEBUGP(4, dev, "Wait for xmit done\n");
+ for (i = 0; i < 1000; i++) {
+ if (inb(REG_FLAGS0(iobase)) & 0x08)
+ break;
+ msleep_interruptible(10);
+ }
+ if (i == 1000) {
+ DEBUGP(4, dev, "timeout waiting for xmit done\n");
+ rc = -EIO;
+ goto release_io;
+ }
+ }
+
+ /* T=1: wait for infoLen */
+
+ infolen = 0;
+ if (dev->proto) {
+ /* wait until infoLen is valid */
+ for (i = 0; i < 6000; i++) { /* max waiting time of 1 min */
+ io_read_num_rec_bytes(iobase, &s);
+ if (s >= 3) {
+ infolen = inb(REG_FLAGS1(iobase));
+ DEBUGP(4, dev, "infolen=%d\n", infolen);
+ break;
+ }
+ msleep_interruptible(10);
+ }
+ if (i == 6000) {
+ DEBUGP(4, dev, "timeout waiting for infoLen\n");
+ rc = -EIO;
+ goto release_io;
+ }
+ } else
+ clear_bit(IS_PROCBYTE_PRESENT, &dev->flags);
+
+ /* numRecBytes | bit9 of numRecytes */
+ io_read_num_rec_bytes(iobase, &dev->rlen);
+ for (i = 0; i < 600; i++) { /* max waiting time of 2 sec */
+ if (dev->proto) {
+ if (dev->rlen >= infolen + 4)
+ break;
+ }
+ msleep_interruptible(10);
+ /* numRecBytes | bit9 of numRecytes */
+ io_read_num_rec_bytes(iobase, &s);
+ if (s > dev->rlen) {
+ DEBUGP(1, dev, "NumRecBytes inc (reset timeout)\n");
+ i = 0; /* reset timeout */
+ dev->rlen = s;
+ }
+ /* T=0: we are done when numRecBytes doesn't
+ * increment any more and NoProcedureByte
+ * is set and numRecBytes == bytes sent + 6
+ * (header bytes + data + 1 for sw2)
+ * except when the card replies an error
+ * which means, no data will be sent back.
+ */
+ else if (dev->proto == 0) {
+ if ((inb(REG_BUF_ADDR(iobase)) & 0x80)) {
+ /* no procedure byte received since last read */
+ DEBUGP(1, dev, "NoProcedure byte set\n");
+ /* i=0; */
+ } else {
+ /* procedure byte received since last read */
+ DEBUGP(1, dev, "NoProcedure byte unset "
+ "(reset timeout)\n");
+ dev->procbyte = inb(REG_FLAGS1(iobase));
+ DEBUGP(1, dev, "Read procedure byte 0x%.2x\n",
+ dev->procbyte);
+ i = 0; /* resettimeout */
+ }
+ if (inb(REG_FLAGS0(iobase)) & 0x08) {
+ DEBUGP(1, dev, "T0Done flag (read reply)\n");
+ break;
+ }
+ }
+ if (dev->proto)
+ infolen = inb(REG_FLAGS1(iobase));
+ }
+ if (i == 600) {
+ DEBUGP(1, dev, "timeout waiting for numRecBytes\n");
+ rc = -EIO;
+ goto release_io;
+ } else {
+ if (dev->proto == 0) {
+ DEBUGP(1, dev, "Wait for T0Done bit to be set\n");
+ for (i = 0; i < 1000; i++) {
+ if (inb(REG_FLAGS0(iobase)) & 0x08)
+ break;
+ msleep_interruptible(10);
+ }
+ if (i == 1000) {
+ DEBUGP(1, dev, "timeout waiting for T0Done\n");
+ rc = -EIO;
+ goto release_io;
+ }
+
+ dev->procbyte = inb(REG_FLAGS1(iobase));
+ DEBUGP(4, dev, "Read procedure byte 0x%.2x\n",
+ dev->procbyte);
+
+ io_read_num_rec_bytes(iobase, &dev->rlen);
+ DEBUGP(4, dev, "Read NumRecBytes = %i\n", dev->rlen);
+
+ }
+ }
+ /* T=1: read offset=zero, T=0: read offset=after challenge */
+ dev->rpos = dev->proto ? 0 : nr == 4 ? 5 : nr > dev->rlen ? 5 : nr;
+ DEBUGP(4, dev, "dev->rlen = %i, dev->rpos = %i, nr = %i\n",
+ dev->rlen, dev->rpos, nr);
+
+release_io:
+ DEBUGP(4, dev, "Reset SM\n");
+ xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */
+
+ if (rc < 0) {
+ DEBUGP(4, dev, "Write failed but clear T_Active\n");
+ dev->flags1 &= 0xdf;
+ xoutb(dev->flags1, REG_FLAGS1(iobase));
+ }
+
+ clear_bit(LOCK_IO, &dev->flags);
+ wake_up_interruptible(&dev->ioq);
+ wake_up_interruptible(&dev->readq); /* tell read we have data */
+
+ /* ITSEC E2: clear write buffer */
+ memset((char *)dev->sbuf, 0, 512);
+
+ /* return error or actually written bytes */
+ DEBUGP(2, dev, "<- cmm_write\n");
+ return rc < 0 ? rc : nr;
+}
+
+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);
+ dev->monitor_running = 1;
+ dev->timer.expires = jiffies;
+ dev->timer.data = (unsigned long) dev;
+ dev->timer.function = monitor_card;
+ add_timer(&dev->timer);
+ } else
+ DEBUGP(5, dev, "monitor already running\n");
+ DEBUGP(3, dev, "<- start_monitor\n");
+}
+
+static void stop_monitor(struct cm4000_dev *dev)
+{
+ DEBUGP(3, dev, "-> stop_monitor\n");
+ if (dev->monitor_running) {
+ DEBUGP(5, dev, "stopping monitor\n");
+ terminate_monitor(dev);
+ /* reset monitor SM */
+ clear_bit(IS_ATR_VALID, &dev->flags);
+ clear_bit(IS_ATR_PRESENT, &dev->flags);
+ } else
+ DEBUGP(5, dev, "monitor already stopped\n");
+ DEBUGP(3, dev, "<- stop_monitor\n");
+}
+
+static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct cm4000_dev *dev = filp->private_data;
+ ioaddr_t iobase = dev->link.io.BasePort1;
+ dev_link_t *link;
+ int size;
+ int rc;
+#ifdef PCMCIA_DEBUG
+ char *ioctl_names[CM_IOC_MAXNR + 1] = {
+ [_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
+ [_IOC_NR(CM_IOCGATR)] "CM_IOCGATR",
+ [_IOC_NR(CM_IOCARDOFF)] "CM_IOCARDOFF",
+ [_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS",
+ [_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL",
+ };
+#endif
+ DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
+ iminor(inode), ioctl_names[_IOC_NR(cmd)]);
+
+ link = dev_table[iminor(inode)];
+ if (!(DEV_OK(link))) {
+ DEBUGP(4, dev, "DEV_OK false\n");
+ return -ENODEV;
+ }
+
+ if (test_bit(IS_CMM_ABSENT, &dev->flags)) {
+ DEBUGP(4, dev, "CMM_ABSENT flag set\n");
+ return -ENODEV;
+ }
+
+ if (_IOC_TYPE(cmd) != CM_IOC_MAGIC) {
+ DEBUGP(4, dev, "ioctype mismatch\n");
+ return -EINVAL;
+ }
+ if (_IOC_NR(cmd) > CM_IOC_MAXNR) {
+ DEBUGP(4, dev, "iocnr mismatch\n");
+ return -EINVAL;
+ }
+ size = _IOC_SIZE(cmd);
+ rc = 0;
+ DEBUGP(4, dev, "iocdir=%.4x iocr=%.4x iocw=%.4x iocsize=%d cmd=%.4x\n",
+ _IOC_DIR(cmd), _IOC_READ, _IOC_WRITE, size, cmd);
+
+ if (_IOC_DIR(cmd) & _IOC_READ) {
+ if (!access_ok(VERIFY_WRITE, (void *)arg, size))
+ return -EFAULT;
+ }
+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
+ if (!access_ok(VERIFY_READ, (void *)arg, size))
+ return -EFAULT;
+ }
+
+ switch (cmd) {
+ case CM_IOCGSTATUS:
+ DEBUGP(4, dev, " ... in CM_IOCGSTATUS\n");
+ {
+ int status;
+
+ /* clear other bits, but leave inserted & powered as
+ * they are */
+ status = dev->flags0 & 3;
+ if (test_bit(IS_ATR_PRESENT, &dev->flags))
+ status |= CM_ATR_PRESENT;
+ if (test_bit(IS_ATR_VALID, &dev->flags))
+ status |= CM_ATR_VALID;
+ if (test_bit(IS_CMM_ABSENT, &dev->flags))
+ status |= CM_NO_READER;
+ if (test_bit(IS_BAD_CARD, &dev->flags))
+ status |= CM_BAD_CARD;
+ if (copy_to_user((int *)arg, &status, sizeof(int)))
+ return -EFAULT;
+ }
+ return 0;
+ case CM_IOCGATR:
+ DEBUGP(4, dev, "... in CM_IOCGATR\n");
+ {
+ struct atreq *atreq = (struct atreq *) arg;
+ int tmp;
+ /* allow nonblocking io and being interrupted */
+ if (wait_event_interruptible
+ (dev->atrq,
+ ((filp->f_flags & O_NONBLOCK)
+ || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
+ != 0)))) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ return -ERESTARTSYS;
+ }
+
+ if (test_bit(IS_ATR_VALID, &dev->flags) == 0) {
+ tmp = -1;
+ if (copy_to_user(&(atreq->atr_len), &tmp,
+ sizeof(int)))
+ return -EFAULT;
+ } else {
+ if (copy_to_user(atreq->atr, dev->atr,
+ dev->atr_len))
+ return -EFAULT;
+
+ tmp = dev->atr_len;
+ if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int)))
+ return -EFAULT;
+ }
+ return 0;
+ }
+ case CM_IOCARDOFF:
+
+#ifdef PCMCIA_DEBUG
+ DEBUGP(4, dev, "... in CM_IOCARDOFF\n");
+ if (dev->flags0 & 0x01) {
+ DEBUGP(4, dev, " Card inserted\n");
+ } else {
+ DEBUGP(2, dev, " No card inserted\n");
+ }
+ if (dev->flags0 & 0x02) {
+ DEBUGP(4, dev, " Card powered\n");
+ } else {
+ DEBUGP(2, dev, " Card not powered\n");
+ }
+#endif
+
+ /* is a card inserted and powered? */
+ if ((dev->flags0 & 0x01) && (dev->flags0 & 0x02)) {
+
+ /* get IO lock */
+ if (wait_event_interruptible
+ (dev->ioq,
+ ((filp->f_flags & O_NONBLOCK)
+ || (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
+ == 0)))) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ return -ERESTARTSYS;
+ }
+ /* Set Flags0 = 0x42 */
+ DEBUGP(4, dev, "Set Flags0=0x42 \n");
+ xoutb(0x42, REG_FLAGS0(iobase));
+ clear_bit(IS_ATR_PRESENT, &dev->flags);
+ clear_bit(IS_ATR_VALID, &dev->flags);
+ dev->mstate = M_CARDOFF;
+ clear_bit(LOCK_IO, &dev->flags);
+ if (wait_event_interruptible
+ (dev->atrq,
+ ((filp->f_flags & O_NONBLOCK)
+ || (test_bit(IS_ATR_VALID, (void *)&dev->flags) !=
+ 0)))) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ return -ERESTARTSYS;
+ }
+ }
+ /* release lock */
+ clear_bit(LOCK_IO, &dev->flags);
+ wake_up_interruptible(&dev->ioq);
+
+ return 0;
+ case CM_IOCSPTS:
+ {
+ struct ptsreq krnptsreq;
+
+ if (copy_from_user(&krnptsreq, (struct ptsreq *) arg,
+ sizeof(struct ptsreq)))
+ return -EFAULT;
+
+ rc = 0;
+ DEBUGP(4, dev, "... in CM_IOCSPTS\n");
+ /* wait for ATR to get valid */
+ if (wait_event_interruptible
+ (dev->atrq,
+ ((filp->f_flags & O_NONBLOCK)
+ || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
+ != 0)))) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ return -ERESTARTSYS;
+ }
+ /* get IO lock */
+ if (wait_event_interruptible
+ (dev->ioq,
+ ((filp->f_flags & O_NONBLOCK)
+ || (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
+ == 0)))) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ return -ERESTARTSYS;
+ }
+
+ if ((rc = set_protocol(dev, &krnptsreq)) != 0) {
+ /* auto power_on again */
+ dev->mstate = M_FETCH_ATR;
+ clear_bit(IS_ATR_VALID, &dev->flags);
+ }
+ /* release lock */
+ clear_bit(LOCK_IO, &dev->flags);
+ wake_up_interruptible(&dev->ioq);
+
+ }
+ return rc;
+#ifdef PCMCIA_DEBUG
+ case CM_IOSDBGLVL: /* set debug log level */
+ {
+ int old_pc_debug = 0;
+
+ old_pc_debug = pc_debug;
+ if (copy_from_user(&pc_debug, (int *)arg, sizeof(int)))
+ return -EFAULT;
+
+ if (old_pc_debug != pc_debug)
+ DEBUGP(0, dev, "Changed debug log level "
+ "to %i\n", pc_debug);
+ }
+ return rc;
+#endif
+ default:
+ DEBUGP(4, dev, "... in default (unknown IOCTL code)\n");
+ return -EINVAL;
+ }
+}
+
+static int cmm_open(struct inode *inode, struct file *filp)
+{
+ struct cm4000_dev *dev;
+ dev_link_t *link;
+ int rc, minor = iminor(inode);
+
+ if (minor >= CM4000_MAX_DEV)
+ return -ENODEV;
+
+ link = dev_table[minor];
+ if (link == NULL || !(DEV_OK(link)))
+ return -ENODEV;
+
+ if (link->open)
+ return -EBUSY;
+
+ dev = link->priv;
+ filp->private_data = dev;
+
+ DEBUGP(2, dev, "-> cmm_open(device=%d.%d process=%s,%d)\n",
+ imajor(inode), minor, current->comm, current->pid);
+
+ /* init device variables, they may be "polluted" after close
+ * or, the device may never have been closed (i.e. open failed)
+ */
+
+ ZERO_DEV(dev);
+
+ /* opening will always block since the
+ * monitor will be started by open, which
+ * means we have to wait for ATR becoming
+ * vaild = block until valid (or card
+ * inserted)
+ */
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ dev->mdelay = T_50MSEC;
+
+ /* start monitoring the cardstatus */
+ start_monitor(dev);
+
+ link->open = 1; /* only one open per device */
+ rc = 0;
+
+ DEBUGP(2, dev, "<- cmm_open\n");
+ return nonseekable_open(inode, filp);
+}
+
+static int cmm_close(struct inode *inode, struct file *filp)
+{
+ struct cm4000_dev *dev;
+ dev_link_t *link;
+ int minor = iminor(inode);
+
+ if (minor >= CM4000_MAX_DEV)
+ return -ENODEV;
+
+ link = dev_table[minor];
+ if (link == NULL)
+ return -ENODEV;
+
+ dev = link->priv;
+
+ DEBUGP(2, dev, "-> cmm_close(maj/min=%d.%d)\n",
+ imajor(inode), minor);
+
+ stop_monitor(dev);
+
+ ZERO_DEV(dev);
+
+ link->open = 0; /* only one open per device */
+ wake_up(&dev->devq); /* socket removed? */
+
+ DEBUGP(2, dev, "cmm_close\n");
+ return 0;
+}
+
+static void cmm_cm4000_release(dev_link_t * link)
+{
+ struct cm4000_dev *dev = link->priv;
+
+ /* dont terminate the monitor, rather rely on
+ * close doing that for us.
+ */
+ DEBUGP(3, dev, "-> cmm_cm4000_release\n");
+ while (link->open) {
+ printk(KERN_INFO MODULE_NAME ": delaying release until "
+ "process has terminated\n");
+ /* note: don't interrupt us:
+ * close the applications which own
+ * the devices _first_ !
+ */
+ wait_event(dev->devq, (link->open == 0));
+ }
+ /* dev->devq=NULL; this cannot be zeroed earlier */
+ DEBUGP(3, dev, "<- cmm_cm4000_release\n");
+ return;
+}
+
+/*==== Interface to PCMCIA Layer =======================================*/
+
+static void cm4000_config(dev_link_t * link, int devno)
+{
+ client_handle_t handle = link->handle;
+ struct cm4000_dev *dev;
+ tuple_t tuple;
+ cisparse_t parse;
+ config_info_t conf;
+ u_char buf[64];
+ int fail_fn, fail_rc;
+ int rc;
+
+ /* read the config-tuples */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+
+ if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) {
+ fail_fn = GetFirstTuple;
+ goto cs_failed;
+ }
+ if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) {
+ fail_fn = GetTupleData;
+ goto cs_failed;
+ }
+ if ((fail_rc =
+ pcmcia_parse_tuple(handle, &tuple, &parse)) != CS_SUCCESS) {
+ fail_fn = ParseTuple;
+ goto cs_failed;
+ }
+ if ((fail_rc =
+ pcmcia_get_configuration_info(handle, &conf)) != CS_SUCCESS) {
+ fail_fn = GetConfigurationInfo;
+ goto cs_failed;
+ }
+
+ link->state |= DEV_CONFIG;
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+ link->conf.Vcc = conf.Vcc;
+
+ link->io.BasePort2 = 0;
+ link->io.NumPorts2 = 0;
+ link->io.Attributes2 = 0;
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ for (rc = pcmcia_get_first_tuple(handle, &tuple);
+ rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(handle, &tuple)) {
+
+ rc = pcmcia_get_tuple_data(handle, &tuple);
+ if (rc != CS_SUCCESS)
+ continue;
+ rc = pcmcia_parse_tuple(handle, &tuple, &parse);
+ if (rc != CS_SUCCESS)
+ continue;
+
+ link->conf.ConfigIndex = parse.cftable_entry.index;
+
+ if (!parse.cftable_entry.io.nwin)
+ continue;
+
+ /* Get the IOaddr */
+ link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
+ link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = parse.cftable_entry.io.flags
+ & CISTPL_IO_LINES_MASK;
+
+ rc = pcmcia_request_io(handle, &link->io);
+ if (rc == CS_SUCCESS)
+ break; /* we are done */
+ }
+ if (rc != CS_SUCCESS)
+ goto cs_release;
+
+ link->conf.IntType = 00000002;
+
+ if ((fail_rc =
+ pcmcia_request_configuration(handle, &link->conf)) != CS_SUCCESS) {
+ fail_fn = RequestConfiguration;
+ goto cs_release;
+ }
+
+ dev = link->priv;
+ sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
+ dev->node.major = major;
+ dev->node.minor = devno;
+ dev->node.next = NULL;
+ link->dev = &dev->node;
+ link->state &= ~DEV_CONFIG_PENDING;
+
+ return;
+
+cs_failed:
+ cs_error(handle, fail_fn, fail_rc);
+cs_release:
+ cm4000_release(link);
+
+ link->state &= ~DEV_CONFIG_PENDING;
+}
+
+static int cm4000_event(event_t event, int priority,
+ event_callback_args_t *args)
+{
+ dev_link_t *link;
+ struct cm4000_dev *dev;
+ int devno;
+
+ link = args->client_data;
+ dev = link->priv;
+
+ DEBUGP(3, dev, "-> cm4000_event\n");
+ for (devno = 0; devno < CM4000_MAX_DEV; devno++)
+ if (dev_table[devno] == link)
+ break;
+
+ if (devno == CM4000_MAX_DEV)
+ return CS_BAD_ADAPTER;
+
+ switch (event) {
+ case CS_EVENT_CARD_INSERTION:
+ DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ cm4000_config(link, devno);
+ break;
+ case CS_EVENT_CARD_REMOVAL:
+ DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
+ link->state &= ~DEV_PRESENT;
+ stop_monitor(dev);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
+ "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
+ link->state |= DEV_SUSPEND;
+ /* fall-through */
+ case CS_EVENT_RESET_PHYSICAL:
+ DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
+ if (link->state & DEV_CONFIG) {
+ DEBUGP(5, dev, "ReleaseConfiguration\n");
+ pcmcia_release_configuration(link->handle);
+ }
+ stop_monitor(dev);
+ break;
+ case CS_EVENT_PM_RESUME:
+ DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
+ "(fall-through to CS_EVENT_CARD_RESET)\n");
+ link->state &= ~DEV_SUSPEND;
+ /* fall-through */
+ case CS_EVENT_CARD_RESET:
+ DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
+ if ((link->state & DEV_CONFIG)) {
+ DEBUGP(5, dev, "RequestConfiguration\n");
+ pcmcia_request_configuration(link->handle, &link->conf);
+ }
+ if (link->open)
+ start_monitor(dev);
+ break;
+ default:
+ DEBUGP(5, dev, "unknown event %.2x\n", event);
+ break;
+ }
+ DEBUGP(3, dev, "<- cm4000_event\n");
+ return CS_SUCCESS;
+}
+
+static void cm4000_release(dev_link_t *link)
+{
+ cmm_cm4000_release(link->priv); /* delay release until device closed */
+ pcmcia_release_configuration(link->handle);
+ pcmcia_release_io(link->handle, &link->io);
+}
+
+static dev_link_t *cm4000_attach(void)
+{
+ struct cm4000_dev *dev;
+ dev_link_t *link;
+ client_reg_t client_reg;
+ int i;
+
+ for (i = 0; i < CM4000_MAX_DEV; i++)
+ if (dev_table[i] == NULL)
+ break;
+
+ if (i == CM4000_MAX_DEV) {
+ printk(KERN_NOTICE MODULE_NAME ": all devices in use\n");
+ return NULL;
+ }
+
+ /* create a new cm4000_cs device */
+ dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL);
+ if (dev == NULL)
+ return NULL;
+
+ link = &dev->link;
+ link->priv = dev;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+ dev_table[i] = link;
+
+ /* register with card services */
+ client_reg.dev_info = &dev_info;
+ client_reg.EventMask =
+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+
+ i = pcmcia_register_client(&link->handle, &client_reg);
+ if (i) {
+ cs_error(link->handle, RegisterClient, i);
+ cm4000_detach(link);
+ return NULL;
+ }
+
+ init_waitqueue_head(&dev->devq);
+ init_waitqueue_head(&dev->ioq);
+ init_waitqueue_head(&dev->atrq);
+ init_waitqueue_head(&dev->readq);
+
+ return link;
+}
+
+static void cm4000_detach_by_devno(int devno, dev_link_t * link)
+{
+ struct cm4000_dev *dev = link->priv;
+
+ DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno);
+
+ if (link->state & DEV_CONFIG) {
+ DEBUGP(5, dev, "device still configured (try to release it)\n");
+ cm4000_release(link);
+ }
+
+ if (link->handle) {
+ pcmcia_deregister_client(link->handle);
+ }
+
+ dev_table[devno] = NULL;
+ kfree(dev);
+ return;
+}
+
+static void cm4000_detach(dev_link_t * link)
+{
+ int i;
+
+ /* find device */
+ for (i = 0; i < CM4000_MAX_DEV; i++)
+ if (dev_table[i] == link)
+ break;
+
+ if (i == CM4000_MAX_DEV)
+ return;
+
+ cm4000_detach_by_devno(i, link);
+ return;
+}
+
+static struct file_operations cm4000_fops = {
+ .owner = THIS_MODULE,
+ .read = cmm_read,
+ .write = cmm_write,
+ .ioctl = cmm_ioctl,
+ .open = cmm_open,
+ .release= cmm_close,
+};
+
+static struct pcmcia_device_id cm4000_ids[] = {
+ PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0002),
+ PCMCIA_DEVICE_PROD_ID12("CardMan", "4000", 0x2FB368CA, 0xA2BD8C39),
+ PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, cm4000_ids);
+
+static struct pcmcia_driver cm4000_driver = {
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = "cm4000_cs",
+ },
+ .attach = cm4000_attach,
+ .detach = cm4000_detach,
+ .event = cm4000_event,
+ .id_table = cm4000_ids,
+};
+
+static int __init cmm_init(void)
+{
+ printk(KERN_INFO "%s\n", version);
+ pcmcia_register_driver(&cm4000_driver);
+ major = register_chrdev(0, DEVICE_NAME, &cm4000_fops);
+ if (major < 0) {
+ printk(KERN_WARNING MODULE_NAME
+ ": could not get major number\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void __exit cmm_exit(void)
+{
+ int i;
+
+ printk(KERN_INFO MODULE_NAME ": unloading\n");
+ pcmcia_unregister_driver(&cm4000_driver);
+ for (i = 0; i < CM4000_MAX_DEV; i++)
+ if (dev_table[i])
+ cm4000_detach_by_devno(i, dev_table[i]);
+ unregister_chrdev(major, DEVICE_NAME);
+};
+
+module_init(cmm_init);
+module_exit(cmm_exit);
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
new file mode 100644
index 0000000..4c698d9
--- /dev/null
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -0,0 +1,841 @@
+/*
+ * A driver for the Omnikey PCMCIA smartcard reader CardMan 4040
+ *
+ * (c) 2000-2004 Omnikey AG (http://www.omnikey.com/)
+ *
+ * (C) 2005 Harald Welte <laforge@gnumonks.org>
+ * - add support for poll()
+ * - driver cleanup
+ * - add waitqueues
+ * - adhere to linux kernel coding style and policies
+ * - support 2.6.13 "new style" pcmcia interface
+ *
+ * The device basically is a USB CCID compliant device that has been
+ * attached to an I/O-Mapped FIFO.
+ *
+ * All rights reserved, Dual BSD/GPL Licensed.
+ */
+
+/* #define PCMCIA_DEBUG 6 */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ciscode.h>
+#include <pcmcia/ds.h>
+
+#include "cm4040_cs.h"
+
+
+#ifdef PCMCIA_DEBUG
+#define reader_to_dev(x) (&handle_to_dev(x->link.handle))
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0600);
+#define DEBUGP(n, rdr, x, args...) do { \
+ if (pc_debug >= (n)) \
+ dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
+ __FUNCTION__ , ##args); \
+ } while (0)
+#else
+#define DEBUGP(n, rdr, x, args...)
+#endif
+
+static char *version =
+"OMNIKEY CardMan 4040 v1.1.0gm4 - All bugs added by Harald Welte";
+
+#define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ)
+#define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ)
+#define CCID_DRIVER_MINIMUM_TIMEOUT (3*HZ)
+#define READ_WRITE_BUFFER_SIZE 512
+#define POLL_LOOP_COUNT 1000
+
+/* how often to poll for fifo status change */
+#define POLL_PERIOD msecs_to_jiffies(10)
+
+static void reader_release(dev_link_t *link);
+static void reader_detach(dev_link_t *link);
+
+static int major;
+
+#define BS_READABLE 0x01
+#define BS_WRITABLE 0x02
+
+struct reader_dev {
+ dev_link_t link;
+ dev_node_t node;
+ wait_queue_head_t devq;
+ wait_queue_head_t poll_wait;
+ wait_queue_head_t read_wait;
+ wait_queue_head_t write_wait;
+ unsigned long buffer_status;
+ unsigned long timeout;
+ unsigned char s_buf[READ_WRITE_BUFFER_SIZE];
+ unsigned char r_buf[READ_WRITE_BUFFER_SIZE];
+ struct timer_list poll_timer;
+};
+
+static dev_info_t dev_info = MODULE_NAME;
+static dev_link_t *dev_table[CM_MAX_DEV];
+
+#ifndef PCMCIA_DEBUG
+#define xoutb outb
+#define xinb inb
+#else
+static inline void xoutb(unsigned char val, unsigned short port)
+{
+ if (pc_debug >= 7)
+ printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
+ outb(val, port);
+}
+
+static inline unsigned char xinb(unsigned short port)
+{
+ unsigned char val;
+
+ val = inb(port);
+ if (pc_debug >= 7)
+ printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
+ return val;
+}
+#endif
+
+/* poll the device fifo status register. not to be confused with
+ * the poll syscall. */
+static void cm4040_do_poll(unsigned long dummy)
+{
+ struct reader_dev *dev = (struct reader_dev *) dummy;
+ unsigned int obs = xinb(dev->link.io.BasePort1
+ + REG_OFFSET_BUFFER_STATUS);
+
+ if ((obs & BSR_BULK_IN_FULL)) {
+ set_bit(BS_READABLE, &dev->buffer_status);
+ DEBUGP(4, dev, "waking up read_wait\n");
+ wake_up_interruptible(&dev->read_wait);
+ } else
+ clear_bit(BS_READABLE, &dev->buffer_status);
+
+ if (!(obs & BSR_BULK_OUT_FULL)) {
+ set_bit(BS_WRITABLE, &dev->buffer_status);
+ DEBUGP(4, dev, "waking up write_wait\n");
+ wake_up_interruptible(&dev->write_wait);
+ } else
+ clear_bit(BS_WRITABLE, &dev->buffer_status);
+
+ if (dev->buffer_status)
+ wake_up_interruptible(&dev->poll_wait);
+
+ mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD);
+}
+
+static void cm4040_stop_poll(struct reader_dev *dev)
+{
+ del_timer_sync(&dev->poll_timer);
+}
+
+static int wait_for_bulk_out_ready(struct reader_dev *dev)
+{
+ int i, rc;
+ int iobase = dev->link.io.BasePort1;
+
+ for (i = 0; i < POLL_LOOP_COUNT; i++) {
+ if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
+ & BSR_BULK_OUT_FULL) == 0) {
+ DEBUGP(4, dev, "BulkOut empty (i=%d)\n", i);
+ return 1;
+ }
+ }
+
+ DEBUGP(4, dev, "wait_event_interruptible_timeout(timeout=%ld\n",
+ dev->timeout);
+ rc = wait_event_interruptible_timeout(dev->write_wait,
+ test_and_clear_bit(BS_WRITABLE,
+ &dev->buffer_status),
+ dev->timeout);
+
+ if (rc > 0)
+ DEBUGP(4, dev, "woke up: BulkOut empty\n");
+ else if (rc == 0)
+ DEBUGP(4, dev, "woke up: BulkOut full, returning 0 :(\n");
+ else if (rc < 0)
+ DEBUGP(4, dev, "woke up: signal arrived\n");
+
+ return rc;
+}
+
+/* Write to Sync Control Register */
+static int write_sync_reg(unsigned char val, struct reader_dev *dev)
+{
+ int iobase = dev->link.io.BasePort1;
+ int rc;
+
+ rc = wait_for_bulk_out_ready(dev);
+ if (rc <= 0)
+ return rc;
+
+ xoutb(val, iobase + REG_OFFSET_SYNC_CONTROL);
+ rc = wait_for_bulk_out_ready(dev);
+ if (rc <= 0)
+ return rc;
+
+ return 1;
+}
+
+static int wait_for_bulk_in_ready(struct reader_dev *dev)
+{
+ int i, rc;
+ int iobase = dev->link.io.BasePort1;
+
+ for (i = 0; i < POLL_LOOP_COUNT; i++) {
+ if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
+ & BSR_BULK_IN_FULL) == BSR_BULK_IN_FULL) {
+ DEBUGP(3, dev, "BulkIn full (i=%d)\n", i);
+ return 1;
+ }
+ }
+
+ DEBUGP(4, dev, "wait_event_interruptible_timeout(timeout=%ld\n",
+ dev->timeout);
+ rc = wait_event_interruptible_timeout(dev->read_wait,
+ test_and_clear_bit(BS_READABLE,
+ &dev->buffer_status),
+ dev->timeout);
+ if (rc > 0)
+ DEBUGP(4, dev, "woke up: BulkIn full\n");
+ else if (rc == 0)
+ DEBUGP(4, dev, "woke up: BulkIn not full, returning 0 :(\n");
+ else if (rc < 0)
+ DEBUGP(4, dev, "woke up: signal arrived\n");
+
+ return rc;
+}
+
+static ssize_t cm4040_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct reader_dev *dev = filp->private_data;
+ int iobase = dev->link.io.BasePort1;
+ size_t bytes_to_read;
+ unsigned long i;
+ size_t min_bytes_to_read;
+ int rc;
+ unsigned char uc;
+
+ DEBUGP(2, dev, "-> cm4040_read(%s,%d)\n", current->comm, current->pid);
+
+ if (count == 0)
+ return 0;
+
+ if (count < 10)
+ return -EFAULT;
+
+ if (filp->f_flags & O_NONBLOCK) {
+ DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n");
+ DEBUGP(2, dev, "<- cm4040_read (failure)\n");
+ return -EAGAIN;
+ }
+
+ if ((dev->link.state & DEV_PRESENT)==0)
+ return -ENODEV;
+
+ for (i = 0; i < 5; i++) {
+ rc = wait_for_bulk_in_ready(dev);
+ if (rc <= 0) {
+ DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc);
+ DEBUGP(2, dev, "<- cm4040_read (failed)\n");
+ if (rc == -ERESTARTSYS)
+ return rc;
+ return -EIO;
+ }
+ dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN);
+#ifdef PCMCIA_DEBUG
+ if (pc_debug >= 6)
+ printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
+ }
+ printk("\n");
+#else
+ }
+#endif
+
+ bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]);
+
+ DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read);
+
+ min_bytes_to_read = min(count, bytes_to_read + 5);
+
+ DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read);
+
+ for (i = 0; i < (min_bytes_to_read-5); i++) {
+ rc = wait_for_bulk_in_ready(dev);
+ if (rc <= 0) {
+ DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc);
+ DEBUGP(2, dev, "<- cm4040_read (failed)\n");
+ if (rc == -ERESTARTSYS)
+ return rc;
+ return -EIO;
+ }
+ dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN);
+#ifdef PCMCIA_DEBUG
+ if (pc_debug >= 6)
+ printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
+ }
+ printk("\n");
+#else
+ }
+#endif
+
+ *ppos = min_bytes_to_read;
+ if (copy_to_user(buf, dev->r_buf, min_bytes_to_read))
+ return -EFAULT;
+
+ rc = wait_for_bulk_in_ready(dev);
+ if (rc <= 0) {
+ DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc);
+ DEBUGP(2, dev, "<- cm4040_read (failed)\n");
+ if (rc == -ERESTARTSYS)
+ return rc;
+ return -EIO;
+ }
+
+ rc = write_sync_reg(SCR_READER_TO_HOST_DONE, dev);
+ if (rc <= 0) {
+ DEBUGP(5, dev, "write_sync_reg c=%.2x\n", rc);
+ DEBUGP(2, dev, "<- cm4040_read (failed)\n");
+ if (rc == -ERESTARTSYS)
+ return rc;
+ else
+ return -EIO;
+ }
+
+ uc = xinb(iobase + REG_OFFSET_BULK_IN);
+
+ DEBUGP(2, dev, "<- cm4040_read (successfully)\n");
+ return min_bytes_to_read;
+}
+
+static ssize_t cm4040_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct reader_dev *dev = filp->private_data;
+ int iobase = dev->link.io.BasePort1;
+ ssize_t rc;
+ int i;
+ unsigned int bytes_to_write;
+
+ DEBUGP(2, dev, "-> cm4040_write(%s,%d)\n", current->comm, current->pid);
+
+ if (count == 0) {
+ DEBUGP(2, dev, "<- cm4040_write empty read (successfully)\n");
+ return 0;
+ }
+
+ if (count < 5) {
+ DEBUGP(2, dev, "<- cm4040_write buffersize=%Zd < 5\n", count);
+ return -EIO;
+ }
+
+ if (filp->f_flags & O_NONBLOCK) {
+ DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n");
+ DEBUGP(4, dev, "<- cm4040_write (failure)\n");
+ return -EAGAIN;
+ }
+
+ if ((dev->link.state & DEV_PRESENT) == 0)
+ return -ENODEV;
+
+ bytes_to_write = count;
+ if (copy_from_user(dev->s_buf, buf, bytes_to_write))
+ return -EFAULT;
+
+ switch (dev->s_buf[0]) {
+ case CMD_PC_TO_RDR_XFRBLOCK:
+ case CMD_PC_TO_RDR_SECURE:
+ case CMD_PC_TO_RDR_TEST_SECURE:
+ case CMD_PC_TO_RDR_OK_SECURE:
+ dev->timeout = CCID_DRIVER_BULK_DEFAULT_TIMEOUT;
+ break;
+
+ case CMD_PC_TO_RDR_ICCPOWERON:
+ dev->timeout = CCID_DRIVER_ASYNC_POWERUP_TIMEOUT;
+ break;
+
+ case CMD_PC_TO_RDR_GETSLOTSTATUS:
+ case CMD_PC_TO_RDR_ICCPOWEROFF:
+ case CMD_PC_TO_RDR_GETPARAMETERS:
+ case CMD_PC_TO_RDR_RESETPARAMETERS:
+ case CMD_PC_TO_RDR_SETPARAMETERS:
+ case CMD_PC_TO_RDR_ESCAPE:
+ case CMD_PC_TO_RDR_ICCCLOCK:
+ default:
+ dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
+ break;
+ }
+
+ rc = write_sync_reg(SCR_HOST_TO_READER_START, dev);
+ if (rc <= 0) {
+ DEBUGP(5, dev, "write_sync_reg c=%.2Zx\n", rc);
+ DEBUGP(2, dev, "<- cm4040_write (failed)\n");
+ if (rc == -ERESTARTSYS)
+ return rc;
+ else
+ return -EIO;
+ }
+
+ DEBUGP(4, dev, "start \n");
+
+ for (i = 0; i < bytes_to_write; i++) {
+ rc = wait_for_bulk_out_ready(dev);
+ if (rc <= 0) {
+ DEBUGP(5, dev, "wait_for_bulk_out_ready rc=%.2Zx\n",
+ rc);
+ DEBUGP(2, dev, "<- cm4040_write (failed)\n");
+ if (rc == -ERESTARTSYS)
+ return rc;
+ else
+ return -EIO;
+ }
+
+ xoutb(dev->s_buf[i],iobase + REG_OFFSET_BULK_OUT);
+ }
+ DEBUGP(4, dev, "end\n");
+
+ rc = write_sync_reg(SCR_HOST_TO_READER_DONE, dev);
+
+ if (rc <= 0) {
+ DEBUGP(5, dev, "write_sync_reg c=%.2Zx\n", rc);
+ DEBUGP(2, dev, "<- cm4040_write (failed)\n");
+ if (rc == -ERESTARTSYS)
+ return rc;
+ else
+ return -EIO;
+ }
+
+ DEBUGP(2, dev, "<- cm4040_write (successfully)\n");
+ return count;
+}
+
+static unsigned int cm4040_poll(struct file *filp, poll_table *wait)
+{
+ struct reader_dev *dev = filp->private_data;
+ unsigned int mask = 0;
+
+ poll_wait(filp, &dev->poll_wait, wait);
+
+ if (test_and_clear_bit(BS_READABLE, &dev->buffer_status))
+ mask |= POLLIN | POLLRDNORM;
+ if (test_and_clear_bit(BS_WRITABLE, &dev->buffer_status))
+ mask |= POLLOUT | POLLWRNORM;
+
+ DEBUGP(2, dev, "<- cm4040_poll(%u)\n", mask);
+
+ return mask;
+}
+
+static int cm4040_open(struct inode *inode, struct file *filp)
+{
+ struct reader_dev *dev;
+ dev_link_t *link;
+ int minor = iminor(inode);
+
+ if (minor >= CM_MAX_DEV)
+ return -ENODEV;
+
+ link = dev_table[minor];
+ if (link == NULL || !(DEV_OK(link)))
+ return -ENODEV;
+
+ if (link->open)
+ return -EBUSY;
+
+ dev = link->priv;
+ filp->private_data = dev;
+
+ if (filp->f_flags & O_NONBLOCK) {
+ DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n");
+ return -EAGAIN;
+ }
+
+ link->open = 1;
+
+ dev->poll_timer.data = (unsigned long) dev;
+ mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD);
+
+ DEBUGP(2, dev, "<- cm4040_open (successfully)\n");
+ return nonseekable_open(inode, filp);
+}
+
+static int cm4040_close(struct inode *inode, struct file *filp)
+{
+ struct reader_dev *dev = filp->private_data;
+ dev_link_t *link;
+ int minor = iminor(inode);
+
+ DEBUGP(2, dev, "-> cm4040_close(maj/min=%d.%d)\n", imajor(inode),
+ iminor(inode));
+
+ if (minor >= CM_MAX_DEV)
+ return -ENODEV;
+
+ link = dev_table[minor];
+ if (link == NULL)
+ return -ENODEV;
+
+ cm4040_stop_poll(dev);
+
+ link->open = 0;
+ wake_up(&dev->devq);
+
+ DEBUGP(2, dev, "<- cm4040_close\n");
+ return 0;
+}
+
+static void cm4040_reader_release(dev_link_t *link)
+{
+ struct reader_dev *dev = link->priv;
+
+ DEBUGP(3, dev, "-> cm4040_reader_release\n");
+ while (link->open) {
+ DEBUGP(3, dev, KERN_INFO MODULE_NAME ": delaying release "
+ "until process has terminated\n");
+ wait_event(dev->devq, (link->open == 0));
+ }
+ DEBUGP(3, dev, "<- cm4040_reader_release\n");
+ return;
+}
+
+static void reader_config(dev_link_t *link, int devno)
+{
+ client_handle_t handle;
+ struct reader_dev *dev;
+ tuple_t tuple;
+ cisparse_t parse;
+ config_info_t conf;
+ u_char buf[64];
+ int fail_fn, fail_rc;
+ int rc;
+
+ handle = link->handle;
+
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+
+ if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) {
+ fail_fn = GetFirstTuple;
+ goto cs_failed;
+ }
+ if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) {
+ fail_fn = GetTupleData;
+ goto cs_failed;
+ }
+ if ((fail_rc = pcmcia_parse_tuple(handle, &tuple, &parse))
+ != CS_SUCCESS) {
+ fail_fn = ParseTuple;
+ goto cs_failed;
+ }
+ if ((fail_rc = pcmcia_get_configuration_info(handle, &conf))
+ != CS_SUCCESS) {
+ fail_fn = GetConfigurationInfo;
+ goto cs_failed;
+ }
+
+ link->state |= DEV_CONFIG;
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+ link->conf.Vcc = conf.Vcc;
+
+ link->io.BasePort2 = 0;
+ link->io.NumPorts2 = 0;
+ link->io.Attributes2 = 0;
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ for (rc = pcmcia_get_first_tuple(handle, &tuple);
+ rc == CS_SUCCESS;
+ rc = pcmcia_get_next_tuple(handle, &tuple)) {
+ rc = pcmcia_get_tuple_data(handle, &tuple);
+ if (rc != CS_SUCCESS)
+ continue;
+ rc = pcmcia_parse_tuple(handle, &tuple, &parse);
+ if (rc != CS_SUCCESS)
+ continue;
+
+ link->conf.ConfigIndex = parse.cftable_entry.index;
+
+ if (!parse.cftable_entry.io.nwin)
+ continue;
+
+ link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
+ link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = parse.cftable_entry.io.flags
+ & CISTPL_IO_LINES_MASK;
+ rc = pcmcia_request_io(handle, &link->io);
+
+ dev_printk(KERN_INFO, &handle_to_dev(handle), "foo");
+ if (rc == CS_SUCCESS)
+ break;
+ else
+ dev_printk(KERN_INFO, &handle_to_dev(handle),
+ "pcmcia_request_io failed 0x%x\n", rc);
+ }
+ if (rc != CS_SUCCESS)
+ goto cs_release;
+
+ link->conf.IntType = 00000002;
+
+ if ((fail_rc = pcmcia_request_configuration(handle,&link->conf))
+ !=CS_SUCCESS) {
+ fail_fn = RequestConfiguration;
+ dev_printk(KERN_INFO, &handle_to_dev(handle),
+ "pcmcia_request_configuration failed 0x%x\n",
+ fail_rc);
+ goto cs_release;
+ }
+
+ dev = link->priv;
+ sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
+ dev->node.major = major;
+ dev->node.minor = devno;
+ dev->node.next = NULL;
+ link->dev = &dev->node;
+ link->state &= ~DEV_CONFIG_PENDING;
+
+ DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno,
+ link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1);
+ DEBUGP(2, dev, "<- reader_config (succ)\n");
+
+ return;
+
+cs_failed:
+ cs_error(handle, fail_fn, fail_rc);
+cs_release:
+ reader_release(link);
+ link->state &= ~DEV_CONFIG_PENDING;
+}
+
+static int reader_event(event_t event, int priority,
+ event_callback_args_t *args)
+{
+ dev_link_t *link;
+ struct reader_dev *dev;
+ int devno;
+
+ link = args->client_data;
+ dev = link->priv;
+ DEBUGP(3, dev, "-> reader_event\n");
+ for (devno = 0; devno < CM_MAX_DEV; devno++) {
+ if (dev_table[devno] == link)
+ break;
+ }
+ if (devno == CM_MAX_DEV)
+ return CS_BAD_ADAPTER;
+
+ switch (event) {
+ case CS_EVENT_CARD_INSERTION:
+ DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ reader_config(link, devno);
+ break;
+ case CS_EVENT_CARD_REMOVAL:
+ DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
+ link->state &= ~DEV_PRESENT;
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
+ "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
+ link->state |= DEV_SUSPEND;
+
+ case CS_EVENT_RESET_PHYSICAL:
+ DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
+ if (link->state & DEV_CONFIG) {
+ DEBUGP(5, dev, "ReleaseConfiguration\n");
+ pcmcia_release_configuration(link->handle);
+ }
+ break;
+ case CS_EVENT_PM_RESUME:
+ DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
+ "(fall-through to CS_EVENT_CARD_RESET)\n");
+ link->state &= ~DEV_SUSPEND;
+
+ case CS_EVENT_CARD_RESET:
+ DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
+ if ((link->state & DEV_CONFIG)) {
+ DEBUGP(5, dev, "RequestConfiguration\n");
+ pcmcia_request_configuration(link->handle,
+ &link->conf);
+ }
+ break;
+ default:
+ DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
+ event);
+ break;
+ }
+ DEBUGP(3, dev, "<- reader_event\n");
+ return CS_SUCCESS;
+}
+
+static void reader_release(dev_link_t *link)
+{
+ cm4040_reader_release(link->priv);
+ pcmcia_release_configuration(link->handle);
+ pcmcia_release_io(link->handle, &link->io);
+}
+
+static dev_link_t *reader_attach(void)
+{
+ struct reader_dev *dev;
+ dev_link_t *link;
+ client_reg_t client_reg;
+ int i;
+
+ for (i = 0; i < CM_MAX_DEV; i++) {
+ if (dev_table[i] == NULL)
+ break;
+ }
+
+ if (i == CM_MAX_DEV)
+ return NULL;
+
+ dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL);
+ if (dev == NULL)
+ return NULL;
+
+ dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
+ dev->buffer_status = 0;
+
+ link = &dev->link;
+ link->priv = dev;
+
+ link->conf.IntType = INT_MEMORY_AND_IO;
+ dev_table[i] = link;
+
+ client_reg.dev_info = &dev_info;
+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+ client_reg.EventMask=
+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+ i = pcmcia_register_client(&link->handle, &client_reg);
+ if (i) {
+ cs_error(link->handle, RegisterClient, i);
+ reader_detach(link);
+ return NULL;
+ }
+ init_waitqueue_head(&dev->devq);
+ 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;
+
+ return link;
+}
+
+static void reader_detach_by_devno(int devno, dev_link_t *link)
+{
+ struct reader_dev *dev = link->priv;
+
+ if (link->state & DEV_CONFIG) {
+ DEBUGP(5, dev, "device still configured (try to release it)\n");
+ reader_release(link);
+ }
+
+ pcmcia_deregister_client(link->handle);
+ dev_table[devno] = NULL;
+ DEBUGP(5, dev, "freeing dev=%p\n", dev);
+ cm4040_stop_poll(dev);
+ kfree(dev);
+ return;
+}
+
+static void reader_detach(dev_link_t *link)
+{
+ int i;
+
+ /* find device */
+ for (i = 0; i < CM_MAX_DEV; i++) {
+ if (dev_table[i] == link)
+ break;
+ }
+ if (i == CM_MAX_DEV)
+ return;
+
+ reader_detach_by_devno(i, link);
+ return;
+}
+
+static struct file_operations reader_fops = {
+ .owner = THIS_MODULE,
+ .read = cm4040_read,
+ .write = cm4040_write,
+ .open = cm4040_open,
+ .release = cm4040_close,
+ .poll = cm4040_poll,
+};
+
+static struct pcmcia_device_id cm4040_ids[] = {
+ PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0200),
+ PCMCIA_DEVICE_PROD_ID12("OMNIKEY", "CardMan 4040",
+ 0xE32CDD8C, 0x8F23318B),
+ PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, cm4040_ids);
+
+static struct pcmcia_driver reader_driver = {
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = "cm4040_cs",
+ },
+ .attach = reader_attach,
+ .detach = reader_detach,
+ .event = reader_event,
+ .id_table = cm4040_ids,
+};
+
+static int __init cm4040_init(void)
+{
+ printk(KERN_INFO "%s\n", version);
+ pcmcia_register_driver(&reader_driver);
+ major = register_chrdev(0, DEVICE_NAME, &reader_fops);
+ if (major < 0) {
+ printk(KERN_WARNING MODULE_NAME
+ ": could not get major number\n");
+ return -1;
+ }
+ return 0;
+}
+
+static void __exit cm4040_exit(void)
+{
+ int i;
+
+ printk(KERN_INFO MODULE_NAME ": unloading\n");
+ pcmcia_unregister_driver(&reader_driver);
+ for (i = 0; i < CM_MAX_DEV; i++) {
+ if (dev_table[i])
+ reader_detach_by_devno(i, dev_table[i]);
+ }
+ unregister_chrdev(major, DEVICE_NAME);
+}
+
+module_init(cm4040_init);
+module_exit(cm4040_exit);
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/char/pcmcia/cm4040_cs.h b/drivers/char/pcmcia/cm4040_cs.h
new file mode 100644
index 0000000..9a8b805
--- /dev/null
+++ b/drivers/char/pcmcia/cm4040_cs.h
@@ -0,0 +1,47 @@
+#ifndef _CM4040_H_
+#define _CM4040_H_
+
+#define CM_MAX_DEV 4
+
+#define DEVICE_NAME "cmx"
+#define MODULE_NAME "cm4040_cs"
+
+#define REG_OFFSET_BULK_OUT 0
+#define REG_OFFSET_BULK_IN 0
+#define REG_OFFSET_BUFFER_STATUS 1
+#define REG_OFFSET_SYNC_CONTROL 2
+
+#define BSR_BULK_IN_FULL 0x02
+#define BSR_BULK_OUT_FULL 0x01
+
+#define SCR_HOST_TO_READER_START 0x80
+#define SCR_ABORT 0x40
+#define SCR_EN_NOTIFY 0x20
+#define SCR_ACK_NOTIFY 0x10
+#define SCR_READER_TO_HOST_DONE 0x08
+#define SCR_HOST_TO_READER_DONE 0x04
+#define SCR_PULSE_INTERRUPT 0x02
+#define SCR_POWER_DOWN 0x01
+
+
+#define CMD_PC_TO_RDR_ICCPOWERON 0x62
+#define CMD_PC_TO_RDR_GETSLOTSTATUS 0x65
+#define CMD_PC_TO_RDR_ICCPOWEROFF 0x63
+#define CMD_PC_TO_RDR_SECURE 0x69
+#define CMD_PC_TO_RDR_GETPARAMETERS 0x6C
+#define CMD_PC_TO_RDR_RESETPARAMETERS 0x6D
+#define CMD_PC_TO_RDR_SETPARAMETERS 0x61
+#define CMD_PC_TO_RDR_XFRBLOCK 0x6F
+#define CMD_PC_TO_RDR_ESCAPE 0x6B
+#define CMD_PC_TO_RDR_ICCCLOCK 0x6E
+#define CMD_PC_TO_RDR_TEST_SECURE 0x74
+#define CMD_PC_TO_RDR_OK_SECURE 0x89
+
+
+#define CMD_RDR_TO_PC_SLOTSTATUS 0x81
+#define CMD_RDR_TO_PC_DATABLOCK 0x80
+#define CMD_RDR_TO_PC_PARAMETERS 0x82
+#define CMD_RDR_TO_PC_ESCAPE 0x83
+#define CMD_RDR_TO_PC_OK_SECURE 0x89
+
+#endif /* _CM4040_H_ */
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
index d724c0d..3df7a57 100644
--- a/drivers/char/s3c2410-rtc.c
+++ b/drivers/char/s3c2410-rtc.c
@@ -382,7 +382,7 @@ static struct rtc_ops s3c2410_rtcops = {
.proc = s3c2410_rtc_proc,
};
-static void s3c2410_rtc_enable(struct device *dev, int en)
+static void s3c2410_rtc_enable(struct platform_device *pdev, int en)
{
unsigned int tmp;
@@ -399,21 +399,21 @@ static void s3c2410_rtc_enable(struct device *dev, int en)
/* re-enable the device, and check it is ok */
if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){
- dev_info(dev, "rtc disabled, re-enabling\n");
+ dev_info(&pdev->dev, "rtc disabled, re-enabling\n");
tmp = readb(S3C2410_RTCCON);
writeb(tmp | S3C2410_RTCCON_RTCEN , S3C2410_RTCCON);
}
if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){
- dev_info(dev, "removing S3C2410_RTCCON_CNTSEL\n");
+ dev_info(&pdev->dev, "removing S3C2410_RTCCON_CNTSEL\n");
tmp = readb(S3C2410_RTCCON);
writeb(tmp& ~S3C2410_RTCCON_CNTSEL , S3C2410_RTCCON);
}
if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){
- dev_info(dev, "removing S3C2410_RTCCON_CLKRST\n");
+ dev_info(&pdev->dev, "removing S3C2410_RTCCON_CLKRST\n");
tmp = readb(S3C2410_RTCCON);
writeb(tmp & ~S3C2410_RTCCON_CLKRST, S3C2410_RTCCON);
@@ -421,7 +421,7 @@ static void s3c2410_rtc_enable(struct device *dev, int en)
}
}
-static int s3c2410_rtc_remove(struct device *dev)
+static int s3c2410_rtc_remove(struct platform_device *dev)
{
unregister_rtc(&s3c2410_rtcops);
@@ -438,25 +438,24 @@ static int s3c2410_rtc_remove(struct device *dev)
return 0;
}
-static int s3c2410_rtc_probe(struct device *dev)
+static int s3c2410_rtc_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
int ret;
- pr_debug("%s: probe=%p, device=%p\n", __FUNCTION__, pdev, dev);
+ pr_debug("%s: probe=%p\n", __FUNCTION__, pdev);
/* find the IRQs */
s3c2410_rtc_tickno = platform_get_irq(pdev, 1);
if (s3c2410_rtc_tickno <= 0) {
- dev_err(dev, "no irq for rtc tick\n");
+ dev_err(&pdev->dev, "no irq for rtc tick\n");
return -ENOENT;
}
s3c2410_rtc_alarmno = platform_get_irq(pdev, 0);
if (s3c2410_rtc_alarmno <= 0) {
- dev_err(dev, "no irq for alarm\n");
+ dev_err(&pdev->dev, "no irq for alarm\n");
return -ENOENT;
}
@@ -467,7 +466,7 @@ static int s3c2410_rtc_probe(struct device *dev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
- dev_err(dev, "failed to get memory region resource\n");
+ dev_err(&pdev->dev, "failed to get memory region resource\n");
return -ENOENT;
}
@@ -475,14 +474,14 @@ static int s3c2410_rtc_probe(struct device *dev)
pdev->name);
if (s3c2410_rtc_mem == NULL) {
- dev_err(dev, "failed to reserve memory region\n");
+ dev_err(&pdev->dev, "failed to reserve memory region\n");
ret = -ENOENT;
goto exit_err;
}
s3c2410_rtc_base = ioremap(res->start, res->end - res->start + 1);
if (s3c2410_rtc_base == NULL) {
- dev_err(dev, "failed ioremap()\n");
+ dev_err(&pdev->dev, "failed ioremap()\n");
ret = -EINVAL;
goto exit_err;
}
@@ -494,7 +493,7 @@ static int s3c2410_rtc_probe(struct device *dev)
/* check to see if everything is setup correctly */
- s3c2410_rtc_enable(dev, 1);
+ s3c2410_rtc_enable(pdev, 1);
pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(S3C2410_RTCCON));
@@ -506,7 +505,7 @@ static int s3c2410_rtc_probe(struct device *dev)
return 0;
exit_err:
- dev_err(dev, "error %d during initialisation\n", ret);
+ dev_err(&pdev->dev, "error %d during initialisation\n", ret);
return ret;
}
@@ -519,7 +518,7 @@ static struct timespec s3c2410_rtc_delta;
static int ticnt_save;
-static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state)
+static int s3c2410_rtc_suspend(struct platform_device *pdev, pm_message_t state)
{
struct rtc_time tm;
struct timespec time;
@@ -535,19 +534,19 @@ static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state)
s3c2410_rtc_gettime(&tm);
rtc_tm_to_time(&tm, &time.tv_sec);
save_time_delta(&s3c2410_rtc_delta, &time);
- s3c2410_rtc_enable(dev, 0);
+ s3c2410_rtc_enable(pdev, 0);
return 0;
}
-static int s3c2410_rtc_resume(struct device *dev)
+static int s3c2410_rtc_resume(struct platform_device *pdev)
{
struct rtc_time tm;
struct timespec time;
time.tv_nsec = 0;
- s3c2410_rtc_enable(dev, 1);
+ s3c2410_rtc_enable(pdev, 1);
s3c2410_rtc_gettime(&tm);
rtc_tm_to_time(&tm, &time.tv_sec);
restore_time_delta(&s3c2410_rtc_delta, &time);
@@ -560,14 +559,15 @@ static int s3c2410_rtc_resume(struct device *dev)
#define s3c2410_rtc_resume NULL
#endif
-static struct device_driver s3c2410_rtcdrv = {
- .name = "s3c2410-rtc",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver s3c2410_rtcdrv = {
.probe = s3c2410_rtc_probe,
.remove = s3c2410_rtc_remove,
.suspend = s3c2410_rtc_suspend,
.resume = s3c2410_rtc_resume,
+ .driver = {
+ .name = "s3c2410-rtc",
+ .owner = THIS_MODULE,
+ },
};
static char __initdata banner[] = "S3C2410 RTC, (c) 2004 Simtec Electronics\n";
@@ -575,12 +575,12 @@ static char __initdata banner[] = "S3C2410 RTC, (c) 2004 Simtec Electronics\n";
static int __init s3c2410_rtc_init(void)
{
printk(banner);
- return driver_register(&s3c2410_rtcdrv);
+ return platform_driver_register(&s3c2410_rtcdrv);
}
static void __exit s3c2410_rtc_exit(void)
{
- driver_unregister(&s3c2410_rtcdrv);
+ platform_driver_unregister(&s3c2410_rtcdrv);
}
module_init(s3c2410_rtc_init);
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index d05067d..51a0737 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -1168,7 +1168,7 @@ static int sonypi_disable(void)
#ifdef CONFIG_PM
static int old_camera_power;
-static int sonypi_suspend(struct device *dev, pm_message_t state)
+static int sonypi_suspend(struct platform_device *dev, pm_message_t state)
{
old_camera_power = sonypi_device.camera_power;
sonypi_disable();
@@ -1176,26 +1176,27 @@ static int sonypi_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int sonypi_resume(struct device *dev)
+static int sonypi_resume(struct platform_device *dev)
{
sonypi_enable(old_camera_power);
return 0;
}
#endif
-static void sonypi_shutdown(struct device *dev)
+static void sonypi_shutdown(struct platform_device *dev)
{
sonypi_disable();
}
-static struct device_driver sonypi_driver = {
- .name = "sonypi",
- .bus = &platform_bus_type,
+static struct platform_driver sonypi_driver = {
#ifdef CONFIG_PM
.suspend = sonypi_suspend,
.resume = sonypi_resume,
#endif
.shutdown = sonypi_shutdown,
+ .driver = {
+ .name = "sonypi",
+ },
};
static int __devinit sonypi_create_input_devices(void)
@@ -1455,20 +1456,20 @@ static int __init sonypi_init(void)
if (!dmi_check_system(sonypi_dmi_table))
return -ENODEV;
- ret = driver_register(&sonypi_driver);
+ ret = platform_driver_register(&sonypi_driver);
if (ret)
return ret;
ret = sonypi_probe();
if (ret)
- driver_unregister(&sonypi_driver);
+ platform_driver_unregister(&sonypi_driver);
return ret;
}
static void __exit sonypi_exit(void)
{
- driver_unregister(&sonypi_driver);
+ platform_driver_unregister(&sonypi_driver);
sonypi_remove();
}
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 5d1ffa3..62aa0e5 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/char/synclink.c
*
- * $Id: synclink.c,v 4.37 2005/09/07 13:13:19 paulkf Exp $
+ * $Id: synclink.c,v 4.38 2005/11/07 16:30:34 paulkf Exp $
*
* Device driver for Microgate SyncLink ISA and PCI
* high speed multiprotocol serial adapters.
@@ -101,6 +101,7 @@
#include <linux/termios.h>
#include <linux/workqueue.h>
#include <linux/hdlc.h>
+#include <linux/dma-mapping.h>
#ifdef CONFIG_HDLC_MODULE
#define CONFIG_HDLC 1
@@ -148,6 +149,7 @@ typedef struct _DMABUFFERENTRY
u32 link; /* 32-bit flat link to next buffer entry */
char *virt_addr; /* virtual address of data buffer */
u32 phys_entry; /* physical address of this buffer entry */
+ dma_addr_t dma_addr;
} DMABUFFERENTRY, *DMAPBUFFERENTRY;
/* The queue of BH actions to be performed */
@@ -233,7 +235,8 @@ struct mgsl_struct {
int ri_chkcount;
char *buffer_list; /* virtual address of Rx & Tx buffer lists */
- unsigned long buffer_list_phys;
+ u32 buffer_list_phys;
+ dma_addr_t buffer_list_dma_addr;
unsigned int rx_buffer_count; /* count of total allocated Rx buffers */
DMABUFFERENTRY *rx_buffer_list; /* list of receive buffer entries */
@@ -896,7 +899,7 @@ module_param_array(txdmabufs, int, NULL, 0);
module_param_array(txholdbufs, int, NULL, 0);
static char *driver_name = "SyncLink serial driver";
-static char *driver_version = "$Revision: 4.37 $";
+static char *driver_version = "$Revision: 4.38 $";
static int synclink_init_one (struct pci_dev *dev,
const struct pci_device_id *ent);
@@ -912,7 +915,6 @@ MODULE_DEVICE_TABLE(pci, synclink_pci_tbl);
MODULE_LICENSE("GPL");
static struct pci_driver synclink_pci_driver = {
- .owner = THIS_MODULE,
.name = "synclink",
.id_table = synclink_pci_tbl,
.probe = synclink_init_one,
@@ -3812,11 +3814,10 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info )
/* inspect portions of the buffer while other portions are being */
/* updated by the adapter using Bus Master DMA. */
- info->buffer_list = kmalloc(BUFFERLISTSIZE, GFP_KERNEL | GFP_DMA);
- if ( info->buffer_list == NULL )
+ info->buffer_list = dma_alloc_coherent(NULL, BUFFERLISTSIZE, &info->buffer_list_dma_addr, GFP_KERNEL);
+ if (info->buffer_list == NULL)
return -ENOMEM;
-
- info->buffer_list_phys = isa_virt_to_bus(info->buffer_list);
+ info->buffer_list_phys = (u32)(info->buffer_list_dma_addr);
}
/* We got the memory for the buffer entry lists. */
@@ -3883,8 +3884,8 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info )
*/
static void mgsl_free_buffer_list_memory( struct mgsl_struct *info )
{
- if ( info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI )
- kfree(info->buffer_list);
+ if (info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI)
+ dma_free_coherent(NULL, BUFFERLISTSIZE, info->buffer_list, info->buffer_list_dma_addr);
info->buffer_list = NULL;
info->rx_buffer_list = NULL;
@@ -3911,7 +3912,7 @@ static void mgsl_free_buffer_list_memory( struct mgsl_struct *info )
static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount)
{
int i;
- unsigned long phys_addr;
+ u32 phys_addr;
/* Allocate page sized buffers for the receive buffer list */
@@ -3923,11 +3924,10 @@ static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *Buff
info->last_mem_alloc += DMABUFFERSIZE;
} else {
/* ISA adapter uses system memory. */
- BufferList[i].virt_addr =
- kmalloc(DMABUFFERSIZE, GFP_KERNEL | GFP_DMA);
- if ( BufferList[i].virt_addr == NULL )
+ BufferList[i].virt_addr = dma_alloc_coherent(NULL, DMABUFFERSIZE, &BufferList[i].dma_addr, GFP_KERNEL);
+ if (BufferList[i].virt_addr == NULL)
return -ENOMEM;
- phys_addr = isa_virt_to_bus(BufferList[i].virt_addr);
+ phys_addr = (u32)(BufferList[i].dma_addr);
}
BufferList[i].phys_addr = phys_addr;
}
@@ -3958,7 +3958,7 @@ static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *Buf
for ( i = 0 ; i < Buffercount ; i++ ) {
if ( BufferList[i].virt_addr ) {
if ( info->bus_type != MGSL_BUS_TYPE_PCI )
- kfree(BufferList[i].virt_addr);
+ dma_free_coherent(NULL, DMABUFFERSIZE, BufferList[i].virt_addr, BufferList[i].dma_addr);
BufferList[i].virt_addr = NULL;
}
}
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 7c063c5..ee5a40b 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -500,7 +500,6 @@ MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl);
MODULE_LICENSE("GPL");
static struct pci_driver synclinkmp_pci_driver = {
- .owner = THIS_MODULE,
.name = "synclinkmp",
.id_table = synclinkmp_pci_tbl,
.probe = synclinkmp_init_one,
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index 24355b2..b3d411a 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -283,7 +283,7 @@ static void tb0219_pci_irq_init(void)
vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, IRQ_LEVEL_LOW);
}
-static int tb0219_probe(struct device *dev)
+static int tb0219_probe(struct platform_device *dev)
{
int retval;
@@ -319,7 +319,7 @@ static int tb0219_probe(struct device *dev)
return 0;
}
-static int tb0219_remove(struct device *dev)
+static int tb0219_remove(struct platform_device *dev)
{
_machine_restart = old_machine_restart;
@@ -333,11 +333,12 @@ static int tb0219_remove(struct device *dev)
static struct platform_device *tb0219_platform_device;
-static struct device_driver tb0219_device_driver = {
- .name = "TB0219",
- .bus = &platform_bus_type,
+static struct platform_driver tb0219_device_driver = {
.probe = tb0219_probe,
.remove = tb0219_remove,
+ .driver = {
+ .name = "TB0219",
+ },
};
static int __devinit tanbac_tb0219_init(void)
@@ -348,7 +349,7 @@ static int __devinit tanbac_tb0219_init(void)
if (IS_ERR(tb0219_platform_device))
return PTR_ERR(tb0219_platform_device);
- retval = driver_register(&tb0219_device_driver);
+ retval = platform_driver_register(&tb0219_device_driver);
if (retval < 0)
platform_device_unregister(tb0219_platform_device);
@@ -357,7 +358,7 @@ static int __devinit tanbac_tb0219_init(void)
static void __devexit tanbac_tb0219_exit(void)
{
- driver_unregister(&tb0219_device_driver);
+ platform_driver_unregister(&tb0219_device_driver);
platform_device_unregister(tb0219_platform_device);
}
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index b58adfe..a6873bf 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -6,7 +6,7 @@ menu "TPM devices"
config TCG_TPM
tristate "TPM Hardware Support"
- depends on EXPERIMENTAL && PCI
+ depends on EXPERIMENTAL
---help---
If you have a TPM security chip in your system, which
implements the Trusted Computing Group's specification,
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 303f158..a9be0e8 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -43,6 +43,13 @@ static void user_reader_timeout(unsigned long ptr)
{
struct tpm_chip *chip = (struct tpm_chip *) ptr;
+ schedule_work(&chip->work);
+}
+
+static void timeout_work(void * ptr)
+{
+ struct tpm_chip *chip = ptr;
+
down(&chip->buffer_mutex);
atomic_set(&chip->data_pending, 0);
memset(chip->data_buffer, 0, TPM_BUFSIZE);
@@ -370,6 +377,7 @@ int tpm_release(struct inode *inode, struct file *file)
file->private_data = NULL;
chip->num_opens--;
del_singleshot_timer_sync(&chip->user_read_timer);
+ flush_scheduled_work();
atomic_set(&chip->data_pending, 0);
put_device(chip->dev);
kfree(chip->data_buffer);
@@ -421,6 +429,7 @@ ssize_t tpm_read(struct file * file, char __user *buf,
int ret_size;
del_singleshot_timer_sync(&chip->user_read_timer);
+ flush_scheduled_work();
ret_size = atomic_read(&chip->data_pending);
atomic_set(&chip->data_pending, 0);
if (ret_size > 0) { /* relay data */
@@ -428,8 +437,7 @@ ssize_t tpm_read(struct file * file, char __user *buf,
ret_size = size;
down(&chip->buffer_mutex);
- if (copy_to_user
- ((void __user *) buf, chip->data_buffer, ret_size))
+ if (copy_to_user(buf, chip->data_buffer, ret_size))
ret_size = -EFAULT;
up(&chip->buffer_mutex);
}
@@ -460,7 +468,7 @@ void tpm_remove_hardware(struct device *dev)
sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
- !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+ ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
kfree(chip);
@@ -528,6 +536,8 @@ int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
init_MUTEX(&chip->tpm_mutex);
INIT_LIST_HEAD(&chip->list);
+ INIT_WORK(&chip->work, timeout_work, chip);
+
init_timer(&chip->user_read_timer);
chip->user_read_timer.function = user_reader_timeout;
chip->user_read_timer.data = (unsigned long) chip;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 9293bcc..159882c 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -50,7 +50,11 @@ struct tpm_vendor_specific {
u8 req_complete_mask;
u8 req_complete_val;
u8 req_canceled;
- u16 base; /* TPM base address */
+ void __iomem *iobase; /* ioremapped address */
+ unsigned long base; /* TPM base address */
+
+ int region_size;
+ int have_region;
int (*recv) (struct tpm_chip *, u8 *, size_t);
int (*send) (struct tpm_chip *, u8 *, size_t);
@@ -73,6 +77,7 @@ struct tpm_chip {
struct semaphore buffer_mutex;
struct timer_list user_read_timer; /* user needs to claim result */
+ struct work_struct work;
struct semaphore tpm_mutex; /* tpm is processing */
struct tpm_vendor_specific *vendor;
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index 32e0145..ff36549 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -19,14 +19,8 @@
*
*/
-#include <linux/platform_device.h>
#include "tpm.h"
-
-/* Atmel definitions */
-enum tpm_atmel_addr {
- TPM_ATMEL_BASE_ADDR_LO = 0x08,
- TPM_ATMEL_BASE_ADDR_HI = 0x09
-};
+#include "tpm_atmel.h"
/* write status bits */
enum tpm_atmel_write_status {
@@ -53,13 +47,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
return -EIO;
for (i = 0; i < 6; i++) {
- status = inb(chip->vendor->base + 1);
+ status = ioread8(chip->vendor->iobase + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
- dev_err(chip->dev,
- "error reading header\n");
+ dev_err(chip->dev, "error reading header\n");
return -EIO;
}
- *buf++ = inb(chip->vendor->base);
+ *buf++ = ioread8(chip->vendor->iobase);
}
/* size of the data received */
@@ -70,10 +63,9 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
dev_err(chip->dev,
"Recv size(%d) less than available space\n", size);
for (; i < size; i++) { /* clear the waiting data anyway */
- status = inb(chip->vendor->base + 1);
+ status = ioread8(chip->vendor->iobase + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
- dev_err(chip->dev,
- "error reading data\n");
+ dev_err(chip->dev, "error reading data\n");
return -EIO;
}
}
@@ -82,17 +74,17 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
/* read all the data available */
for (; i < size; i++) {
- status = inb(chip->vendor->base + 1);
+ status = ioread8(chip->vendor->iobase + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
- dev_err(chip->dev,
- "error reading data\n");
+ dev_err(chip->dev, "error reading data\n");
return -EIO;
}
- *buf++ = inb(chip->vendor->base);
+ *buf++ = ioread8(chip->vendor->iobase);
}
/* make sure data available is gone */
- status = inb(chip->vendor->base + 1);
+ status = ioread8(chip->vendor->iobase + 1);
+
if (status & ATML_STATUS_DATA_AVAIL) {
dev_err(chip->dev, "data available is stuck\n");
return -EIO;
@@ -108,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
dev_dbg(chip->dev, "tpm_atml_send:\n");
for (i = 0; i < count; i++) {
dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]);
- outb(buf[i], chip->vendor->base);
+ iowrite8(buf[i], chip->vendor->iobase);
}
return count;
@@ -116,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
static void tpm_atml_cancel(struct tpm_chip *chip)
{
- outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
+ iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
}
static u8 tpm_atml_status(struct tpm_chip *chip)
{
- return inb(chip->vendor->base + 1);
+ return ioread8(chip->vendor->iobase + 1);
}
static struct file_operations atmel_ops = {
@@ -162,12 +154,17 @@ static struct tpm_vendor_specific tpm_atmel = {
static struct platform_device *pdev;
-static void __devexit tpm_atml_remove(struct device *dev)
+static void atml_plat_remove(void)
{
- struct tpm_chip *chip = dev_get_drvdata(dev);
+ struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
+
if (chip) {
- release_region(chip->vendor->base, 2);
+ if (chip->vendor->have_region)
+ atmel_release_region(chip->vendor->base,
+ chip->vendor->region_size);
+ atmel_put_base_addr(chip->vendor);
tpm_remove_hardware(chip->dev);
+ platform_device_unregister(pdev);
}
}
@@ -182,72 +179,46 @@ static struct device_driver atml_drv = {
static int __init init_atmel(void)
{
int rc = 0;
- int lo, hi;
driver_register(&atml_drv);
- lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
- hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
-
- tpm_atmel.base = (hi<<8)|lo;
-
- /* verify that it is an Atmel part */
- if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
- || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
- return -ENODEV;
+ if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
+ rc = -ENODEV;
+ goto err_unreg_drv;
}
- /* verify chip version number is 1.1 */
- if ( (tpm_read_index(TPM_ADDR, 0x00) != 0x01) ||
- (tpm_read_index(TPM_ADDR, 0x01) != 0x01 ))
- return -ENODEV;
-
- pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
- if ( !pdev )
- return -ENOMEM;
-
- pdev->name = "tpm_atmel0";
- pdev->id = -1;
- pdev->num_resources = 0;
- pdev->dev.release = tpm_atml_remove;
- pdev->dev.driver = &atml_drv;
-
- if ((rc = platform_device_register(pdev)) < 0) {
- kfree(pdev);
- pdev = NULL;
- return rc;
- }
+ tpm_atmel.have_region =
+ (atmel_request_region
+ (tpm_atmel.base, tpm_atmel.region_size,
+ "tpm_atmel0") == NULL) ? 0 : 1;
- if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) {
- platform_device_unregister(pdev);
- kfree(pdev);
- pdev = NULL;
- return -EBUSY;
+ if (IS_ERR
+ (pdev =
+ platform_device_register_simple("tpm_atmel", -1, NULL, 0))) {
+ rc = PTR_ERR(pdev);
+ goto err_rel_reg;
}
- if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) {
- release_region(tpm_atmel.base, 2);
- platform_device_unregister(pdev);
- kfree(pdev);
- pdev = NULL;
- return rc;
- }
-
- dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n",
- tpm_atmel.base);
+ if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
+ goto err_unreg_dev;
return 0;
+
+err_unreg_dev:
+ platform_device_unregister(pdev);
+err_rel_reg:
+ atmel_put_base_addr(&tpm_atmel);
+ if (tpm_atmel.have_region)
+ atmel_release_region(tpm_atmel.base,
+ tpm_atmel.region_size);
+err_unreg_drv:
+ driver_unregister(&atml_drv);
+ return rc;
}
static void __exit cleanup_atmel(void)
{
- if (pdev) {
- tpm_atml_remove(&pdev->dev);
- platform_device_unregister(pdev);
- kfree(pdev);
- pdev = NULL;
- }
-
driver_unregister(&atml_drv);
+ atml_plat_remove();
}
module_init(init_atmel);
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h
new file mode 100644
index 0000000..d3478aa
--- /dev/null
+++ b/drivers/char/tpm/tpm_atmel.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Authors:
+ * Kylene Hall <kjhall@us.ibm.com>
+ *
+ * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * 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.
+ *
+ * These difference are required on power because the device must be
+ * discovered through the device tree and iomap must be used to get
+ * around the need for holes in the io_page_mask. This does not happen
+ * automatically because the tpm is not a normal pci device and lives
+ * under the root node.
+ *
+ */
+
+#ifdef CONFIG_PPC64
+#define atmel_getb(chip, offset) readb(chip->vendor->iobase + offset);
+#define atmel_putb(val, chip, offset) writeb(val, chip->vendor->iobase + offset)
+#define atmel_request_region request_mem_region
+#define atmel_release_region release_mem_region
+
+static inline void atmel_put_base_addr(struct tpm_vendor_specific
+ *vendor)
+{
+ iounmap(vendor->iobase);
+}
+
+static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
+{
+ struct device_node *dn;
+ unsigned long address, size;
+ unsigned int *reg;
+ int reglen;
+ int naddrc;
+ int nsizec;
+
+ dn = of_find_node_by_name(NULL, "tpm");
+
+ if (!dn)
+ return NULL;
+
+ if (!device_is_compatible(dn, "AT97SC3201")) {
+ of_node_put(dn);
+ return NULL;
+ }
+
+ reg = (unsigned int *) get_property(dn, "reg", &reglen);
+ naddrc = prom_n_addr_cells(dn);
+ nsizec = prom_n_size_cells(dn);
+
+ of_node_put(dn);
+
+
+ if (naddrc == 2)
+ address = ((unsigned long) reg[0] << 32) | reg[1];
+ else
+ address = reg[0];
+
+ if (nsizec == 2)
+ size =
+ ((unsigned long) reg[naddrc] << 32) | reg[naddrc + 1];
+ else
+ size = reg[naddrc];
+
+ vendor->base = address;
+ vendor->region_size = size;
+ return ioremap(vendor->base, vendor->region_size);
+}
+#else
+#define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
+#define atmel_putb(val, chip, offset) outb(val, chip->vendor->base + offset)
+#define atmel_request_region request_region
+#define atmel_release_region release_region
+/* Atmel definitions */
+enum tpm_atmel_addr {
+ TPM_ATMEL_BASE_ADDR_LO = 0x08,
+ TPM_ATMEL_BASE_ADDR_HI = 0x09
+};
+
+/* Verify this is a 1.1 Atmel TPM */
+static int atmel_verify_tpm11(void)
+{
+
+ /* verify that it is an Atmel part */
+ if (tpm_read_index(TPM_ADDR, 4) != 'A' ||
+ tpm_read_index(TPM_ADDR, 5) != 'T' ||
+ tpm_read_index(TPM_ADDR, 6) != 'M' ||
+ tpm_read_index(TPM_ADDR, 7) != 'L')
+ return 1;
+
+ /* query chip for its version number */
+ if (tpm_read_index(TPM_ADDR, 0x00) != 1 ||
+ tpm_read_index(TPM_ADDR, 0x01) != 1)
+ return 1;
+
+ /* This is an atmel supported part */
+ return 0;
+}
+
+static inline void atmel_put_base_addr(struct tpm_vendor_specific
+ *vendor)
+{
+}
+
+/* Determine where to talk to device */
+static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
+ *vendor)
+{
+ int lo, hi;
+
+ if (atmel_verify_tpm11() != 0)
+ return NULL;
+
+ lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
+ hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
+
+ vendor->base = (hi << 8) | lo;
+ vendor->region_size = 2;
+
+ return ioport_map(vendor->base, vendor->region_size);
+}
+#endif
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index 9464108..9ac6d43 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -613,7 +613,7 @@ static struct file_operations gpio_fops = {
.release = gpio_release,
};
-static int giu_probe(struct device *dev)
+static int giu_probe(struct platform_device *dev)
{
unsigned long start, size, flags = 0;
unsigned int nr_pins = 0;
@@ -697,7 +697,7 @@ static int giu_probe(struct device *dev)
return cascade_irq(GIUINT_IRQ, giu_get_irq);
}
-static int giu_remove(struct device *dev)
+static int giu_remove(struct platform_device *dev)
{
iounmap(giu_base);
@@ -710,11 +710,12 @@ static int giu_remove(struct device *dev)
static struct platform_device *giu_platform_device;
-static struct device_driver giu_device_driver = {
- .name = "GIU",
- .bus = &platform_bus_type,
+static struct platform_driver giu_device_driver = {
.probe = giu_probe,
.remove = giu_remove,
+ .driver = {
+ .name = "GIU",
+ },
};
static int __devinit vr41xx_giu_init(void)
@@ -725,7 +726,7 @@ static int __devinit vr41xx_giu_init(void)
if (IS_ERR(giu_platform_device))
return PTR_ERR(giu_platform_device);
- retval = driver_register(&giu_device_driver);
+ retval = platform_driver_register(&giu_device_driver);
if (retval < 0)
platform_device_unregister(giu_platform_device);
@@ -734,7 +735,7 @@ static int __devinit vr41xx_giu_init(void)
static void __devexit vr41xx_giu_exit(void)
{
- driver_unregister(&giu_device_driver);
+ platform_driver_unregister(&giu_device_driver);
platform_device_unregister(giu_platform_device);
}
diff --git a/drivers/char/vr41xx_rtc.c b/drivers/char/vr41xx_rtc.c
index 5e3292d..435b307 100644
--- a/drivers/char/vr41xx_rtc.c
+++ b/drivers/char/vr41xx_rtc.c
@@ -560,13 +560,11 @@ static struct miscdevice rtc_miscdevice = {
.fops = &rtc_fops,
};
-static int rtc_probe(struct device *dev)
+static int rtc_probe(struct platform_device *pdev)
{
- struct platform_device *pdev;
unsigned int irq;
int retval;
- pdev = to_platform_device(dev);
if (pdev->num_resources != 2)
return -EBUSY;
@@ -635,7 +633,7 @@ static int rtc_probe(struct device *dev)
return 0;
}
-static int rtc_remove(struct device *dev)
+static int rtc_remove(struct platform_device *dev)
{
int retval;
@@ -655,11 +653,12 @@ static int rtc_remove(struct device *dev)
static struct platform_device *rtc_platform_device;
-static struct device_driver rtc_device_driver = {
- .name = rtc_name,
- .bus = &platform_bus_type,
+static struct platform_driver rtc_device_driver = {
.probe = rtc_probe,
.remove = rtc_remove,
+ .driver = {
+ .name = rtc_name,
+ },
};
static int __devinit vr41xx_rtc_init(void)
@@ -691,7 +690,7 @@ static int __devinit vr41xx_rtc_init(void)
if (IS_ERR(rtc_platform_device))
return PTR_ERR(rtc_platform_device);
- retval = driver_register(&rtc_device_driver);
+ retval = platform_driver_register(&rtc_device_driver);
if (retval < 0)
platform_device_unregister(rtc_platform_device);
@@ -700,7 +699,7 @@ static int __devinit vr41xx_rtc_init(void)
static void __devexit vr41xx_rtc_exit(void)
{
- driver_unregister(&rtc_device_driver);
+ platform_driver_unregister(&rtc_device_driver);
platform_device_unregister(rtc_platform_device);
}
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c
index abc30cc..65830ec 100644
--- a/drivers/char/watchdog/booke_wdt.c
+++ b/drivers/char/watchdog/booke_wdt.c
@@ -4,7 +4,7 @@
* Watchdog timer for PowerPC Book-E systems
*
* Author: Matthew McClintock
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
*
* Copyright 2005 Freescale Semiconductor Inc.
*
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
index da631c1..9defcf8 100644
--- a/drivers/char/watchdog/mpcore_wdt.c
+++ b/drivers/char/watchdog/mpcore_wdt.c
@@ -139,7 +139,7 @@ static int mpcore_wdt_set_heartbeat(int t)
*/
static int mpcore_wdt_open(struct inode *inode, struct file *file)
{
- struct mpcore_wdt *wdt = dev_get_drvdata(&mpcore_wdt_dev->dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(mpcore_wdt_dev);
if (test_and_set_bit(0, &wdt->timer_alive))
return -EBUSY;
@@ -291,9 +291,9 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file,
* System shutdown handler. Turn off the watchdog if we're
* restarting or halting the system.
*/
-static void mpcore_wdt_shutdown(struct device *_dev)
+static void mpcore_wdt_shutdown(struct platform_device *dev)
{
- struct mpcore_wdt *wdt = dev_get_drvdata(_dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(dev);
if (system_state == SYSTEM_RESTART || system_state == SYSTEM_HALT)
mpcore_wdt_stop(wdt);
@@ -317,9 +317,8 @@ static struct miscdevice mpcore_wdt_miscdev = {
.fops = &mpcore_wdt_fops,
};
-static int __devinit mpcore_wdt_probe(struct device *_dev)
+static int __devinit mpcore_wdt_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
struct mpcore_wdt *wdt;
struct resource *res;
int ret;
@@ -364,7 +363,7 @@ static int __devinit mpcore_wdt_probe(struct device *_dev)
}
mpcore_wdt_stop(wdt);
- dev_set_drvdata(&dev->dev, wdt);
+ platform_set_drvdata(&dev->dev, wdt);
mpcore_wdt_dev = dev;
return 0;
@@ -379,11 +378,11 @@ static int __devinit mpcore_wdt_probe(struct device *_dev)
return ret;
}
-static int __devexit mpcore_wdt_remove(struct device *dev)
+static int __devexit mpcore_wdt_remove(struct platform_device *dev)
{
- struct mpcore_wdt *wdt = dev_get_drvdata(dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(dev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
misc_deregister(&mpcore_wdt_miscdev);
@@ -395,13 +394,14 @@ static int __devexit mpcore_wdt_remove(struct device *dev)
return 0;
}
-static struct device_driver mpcore_wdt_driver = {
- .owner = THIS_MODULE,
- .name = "mpcore_wdt",
- .bus = &platform_bus_type,
+static struct platform_driver mpcore_wdt_driver = {
.probe = mpcore_wdt_probe,
.remove = __devexit_p(mpcore_wdt_remove),
.shutdown = mpcore_wdt_shutdown,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "mpcore_wdt",
+ },
};
static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. mpcore_noboot=%d mpcore_margin=%d sec (nowayout= %d)\n";
@@ -420,12 +420,12 @@ static int __init mpcore_wdt_init(void)
printk(banner, mpcore_noboot, mpcore_margin, nowayout);
- return driver_register(&mpcore_wdt_driver);
+ return platform_driver_register(&mpcore_wdt_driver);
}
static void __exit mpcore_wdt_exit(void)
{
- driver_unregister(&mpcore_wdt_driver);
+ platform_driver_unregister(&mpcore_wdt_driver);
}
module_init(mpcore_wdt_init);
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
index 119b3c5..00d9ef0 100644
--- a/drivers/char/watchdog/mv64x60_wdt.c
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -182,10 +182,9 @@ static struct miscdevice mv64x60_wdt_miscdev = {
.fops = &mv64x60_wdt_fops,
};
-static int __devinit mv64x60_wdt_probe(struct device *dev)
+static int __devinit mv64x60_wdt_probe(struct platform_device *dev)
{
- struct platform_device *pd = to_platform_device(dev);
- struct mv64x60_wdt_pdata *pdata = pd->dev.platform_data;
+ struct mv64x60_wdt_pdata *pdata = dev->dev.platform_data;
int bus_clk = 133;
mv64x60_wdt_timeout = 10;
@@ -202,7 +201,7 @@ static int __devinit mv64x60_wdt_probe(struct device *dev)
return misc_register(&mv64x60_wdt_miscdev);
}
-static int __devexit mv64x60_wdt_remove(struct device *dev)
+static int __devexit mv64x60_wdt_remove(struct platform_device *dev)
{
misc_deregister(&mv64x60_wdt_miscdev);
@@ -212,12 +211,13 @@ static int __devexit mv64x60_wdt_remove(struct device *dev)
return 0;
}
-static struct device_driver mv64x60_wdt_driver = {
- .owner = THIS_MODULE,
- .name = MV64x60_WDT_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver mv64x60_wdt_driver = {
.probe = mv64x60_wdt_probe,
.remove = __devexit_p(mv64x60_wdt_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = MV64x60_WDT_NAME,
+ },
};
static struct platform_device *mv64x60_wdt_dev;
@@ -235,14 +235,14 @@ static int __init mv64x60_wdt_init(void)
goto out;
}
- ret = driver_register(&mv64x60_wdt_driver);
+ ret = platform_driver_register(&mv64x60_wdt_driver);
out:
return ret;
}
static void __exit mv64x60_wdt_exit(void)
{
- driver_unregister(&mv64x60_wdt_driver);
+ platform_driver_unregister(&mv64x60_wdt_driver);
platform_device_unregister(mv64x60_wdt_dev);
}
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index d9ef55b..2451edb 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -755,7 +755,6 @@ static struct pci_device_id pcipcwd_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl);
static struct pci_driver pcipcwd_driver = {
- .owner = THIS_MODULE,
.name = WATCHDOG_NAME,
.id_table = pcipcwd_pci_tbl,
.probe = pcipcwd_card_init,
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index 751cb77..eb667da 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -347,15 +347,14 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param,
}
/* device interface */
-static int s3c2410wdt_probe(struct device *dev)
+static int s3c2410wdt_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
int started = 0;
int ret;
int size;
- DBG("%s: probe=%p, device=%p\n", __FUNCTION__, pdev, dev);
+ DBG("%s: probe=%p\n", __FUNCTION__, pdev);
/* get the memory region for the watchdog timer */
@@ -386,13 +385,13 @@ static int s3c2410wdt_probe(struct device *dev)
return -ENOENT;
}
- ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, dev);
+ ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev);
if (ret != 0) {
printk(KERN_INFO PFX "failed to install irq (%d)\n", ret);
return ret;
}
- wdt_clock = clk_get(dev, "watchdog");
+ wdt_clock = clk_get(&pdev->dev, "watchdog");
if (wdt_clock == NULL) {
printk(KERN_INFO PFX "failed to find watchdog clock source\n");
return -ENOENT;
@@ -430,7 +429,7 @@ static int s3c2410wdt_probe(struct device *dev)
return 0;
}
-static int s3c2410wdt_remove(struct device *dev)
+static int s3c2410wdt_remove(struct platform_device *dev)
{
if (wdt_mem != NULL) {
release_resource(wdt_mem);
@@ -454,7 +453,7 @@ static int s3c2410wdt_remove(struct device *dev)
return 0;
}
-static void s3c2410wdt_shutdown(struct device *dev)
+static void s3c2410wdt_shutdown(struct platform_device *dev)
{
s3c2410wdt_stop();
}
@@ -464,7 +463,7 @@ static void s3c2410wdt_shutdown(struct device *dev)
static unsigned long wtcon_save;
static unsigned long wtdat_save;
-static int s3c2410wdt_suspend(struct device *dev, pm_message_t state)
+static int s3c2410wdt_suspend(struct platform_device *dev, pm_message_t state)
{
/* Save watchdog state, and turn it off. */
wtcon_save = readl(wdt_base + S3C2410_WTCON);
@@ -476,7 +475,7 @@ static int s3c2410wdt_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int s3c2410wdt_resume(struct device *dev)
+static int s3c2410wdt_resume(struct platform_device *dev)
{
/* Restore watchdog state. */
@@ -496,15 +495,16 @@ static int s3c2410wdt_resume(struct device *dev)
#endif /* CONFIG_PM */
-static struct device_driver s3c2410wdt_driver = {
- .owner = THIS_MODULE,
- .name = "s3c2410-wdt",
- .bus = &platform_bus_type,
+static struct platform_driver s3c2410wdt_driver = {
.probe = s3c2410wdt_probe,
.remove = s3c2410wdt_remove,
.shutdown = s3c2410wdt_shutdown,
.suspend = s3c2410wdt_suspend,
.resume = s3c2410wdt_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s3c2410-wdt",
+ },
};
@@ -513,12 +513,12 @@ static char banner[] __initdata = KERN_INFO "S3C2410 Watchdog Timer, (c) 2004 Si
static int __init watchdog_init(void)
{
printk(banner);
- return driver_register(&s3c2410wdt_driver);
+ return platform_driver_register(&s3c2410wdt_driver);
}
static void __exit watchdog_exit(void)
{
- driver_unregister(&s3c2410wdt_driver);
+ platform_driver_unregister(&s3c2410wdt_driver);
}
module_init(watchdog_init);
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
index dc9370f..4b33119 100644
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/char/watchdog/wdt_pci.c
@@ -711,7 +711,6 @@ MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl);
static struct pci_driver wdtpci_driver = {
- .owner = THIS_MODULE,
.name = "wdt_pci",
.id_table = wdtpci_pci_tbl,
.probe = wdtpci_init_one,
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 1e5dfc7..c81bd4b 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -60,9 +60,11 @@
#define HDAPS_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */
#define HDAPS_INPUT_FUZZ 4 /* input event threshold */
+#define HDAPS_INPUT_FLAT 4
static struct timer_list hdaps_timer;
static struct platform_device *pdev;
+static struct input_dev *hdaps_idev;
static unsigned int hdaps_invert;
static u8 km_activity;
static int rest_x;
@@ -284,7 +286,7 @@ out:
/* Device model stuff */
-static int hdaps_probe(struct device *dev)
+static int hdaps_probe(struct platform_device *dev)
{
int ret;
@@ -296,29 +298,18 @@ static int hdaps_probe(struct device *dev)
return 0;
}
-static int hdaps_resume(struct device *dev)
+static int hdaps_resume(struct platform_device *dev)
{
return hdaps_device_init();
}
-static struct device_driver hdaps_driver = {
- .name = "hdaps",
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
+static struct platform_driver hdaps_driver = {
.probe = hdaps_probe,
- .resume = hdaps_resume
-};
-
-/* Input class stuff */
-
-static struct input_dev hdaps_idev = {
- .name = "hdaps",
- .evbit = { BIT(EV_ABS) },
- .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
- .absmin = { [ABS_X] = -256, [ABS_Y] = -256 },
- .absmax = { [ABS_X] = 256, [ABS_Y] = 256 },
- .absfuzz = { [ABS_X] = HDAPS_INPUT_FUZZ, [ABS_Y] = HDAPS_INPUT_FUZZ },
- .absflat = { [ABS_X] = HDAPS_INPUT_FUZZ, [ABS_Y] = HDAPS_INPUT_FUZZ },
+ .resume = hdaps_resume,
+ .driver = {
+ .name = "hdaps",
+ .owner = THIS_MODULE,
+ },
};
/*
@@ -342,9 +333,9 @@ static void hdaps_mousedev_poll(unsigned long unused)
if (__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y))
goto out;
- input_report_abs(&hdaps_idev, ABS_X, x - rest_x);
- input_report_abs(&hdaps_idev, ABS_Y, y - rest_y);
- input_sync(&hdaps_idev);
+ input_report_abs(hdaps_idev, ABS_X, x - rest_x);
+ input_report_abs(hdaps_idev, ABS_Y, y - rest_y);
+ input_sync(hdaps_idev);
mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD);
@@ -550,7 +541,7 @@ static int __init hdaps_init(void)
goto out;
}
- ret = driver_register(&hdaps_driver);
+ ret = platform_driver_register(&hdaps_driver);
if (ret)
goto out_region;
@@ -564,12 +555,25 @@ static int __init hdaps_init(void)
if (ret)
goto out_device;
+ hdaps_idev = input_allocate_device();
+ if (!hdaps_idev) {
+ ret = -ENOMEM;
+ goto out_group;
+ }
+
/* initial calibrate for the input device */
hdaps_calibrate();
/* initialize the input class */
- hdaps_idev.dev = &pdev->dev;
- input_register_device(&hdaps_idev);
+ hdaps_idev->name = "hdaps";
+ hdaps_idev->cdev.dev = &pdev->dev;
+ hdaps_idev->evbit[0] = BIT(EV_ABS);
+ input_set_abs_params(hdaps_idev, ABS_X,
+ -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
+ input_set_abs_params(hdaps_idev, ABS_X,
+ -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
+
+ input_register_device(hdaps_idev);
/* start up our timer for the input device */
init_timer(&hdaps_timer);
@@ -580,10 +584,12 @@ static int __init hdaps_init(void)
printk(KERN_INFO "hdaps: driver successfully loaded.\n");
return 0;
+out_group:
+ sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
out_device:
platform_device_unregister(pdev);
out_driver:
- driver_unregister(&hdaps_driver);
+ platform_driver_unregister(&hdaps_driver);
out_region:
release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS);
out:
@@ -594,10 +600,10 @@ out:
static void __exit hdaps_exit(void)
{
del_timer_sync(&hdaps_timer);
- input_unregister_device(&hdaps_idev);
+ input_unregister_device(hdaps_idev);
sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
platform_device_unregister(pdev);
- driver_unregister(&hdaps_driver);
+ platform_driver_unregister(&hdaps_driver);
release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS);
printk(KERN_INFO "hdaps: driver unloaded.\n");
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
index ba90f51..3eb4789 100644
--- a/drivers/i2c/busses/i2c-ali1535.c
+++ b/drivers/i2c/busses/i2c-ali1535.c
@@ -513,7 +513,6 @@ static void __devexit ali1535_remove(struct pci_dev *dev)
}
static struct pci_driver ali1535_driver = {
- .owner = THIS_MODULE,
.name = "ali1535_smbus",
.id_table = ali1535_ids,
.probe = ali1535_probe,
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
index f1a62d8..e6f6320 100644
--- a/drivers/i2c/busses/i2c-ali1563.c
+++ b/drivers/i2c/busses/i2c-ali1563.c
@@ -408,7 +408,6 @@ static struct pci_device_id __devinitdata ali1563_id_table[] = {
MODULE_DEVICE_TABLE (pci, ali1563_id_table);
static struct pci_driver ali1563_pci_driver = {
- .owner = THIS_MODULE,
.name = "ali1563_smbus",
.id_table = ali1563_id_table,
.probe = ali1563_probe,
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
index 400b08e..7a5c094 100644
--- a/drivers/i2c/busses/i2c-ali15x3.c
+++ b/drivers/i2c/busses/i2c-ali15x3.c
@@ -504,7 +504,6 @@ static void __devexit ali15x3_remove(struct pci_dev *dev)
}
static struct pci_driver ali15x3_driver = {
- .owner = THIS_MODULE,
.name = "ali15x3_smbus",
.id_table = ali15x3_ids,
.probe = ali15x3_probe,
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index de035d1..1750ded 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -401,7 +401,6 @@ static void __devexit amd756_remove(struct pci_dev *dev)
}
static struct pci_driver amd756_driver = {
- .owner = THIS_MODULE,
.name = "amd756_smbus",
.id_table = amd756_ids,
.probe = amd756_probe,
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index f3b79a6..e5ef560 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -384,7 +384,6 @@ static void __devexit amd8111_remove(struct pci_dev *dev)
}
static struct pci_driver amd8111_driver = {
- .owner = THIS_MODULE,
.name = "amd8111_smbus2",
.id_table = amd8111_ids,
.probe = amd8111_probe,
diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
index 1b5354e..e0cb3b0 100644
--- a/drivers/i2c/busses/i2c-hydra.c
+++ b/drivers/i2c/busses/i2c-hydra.c
@@ -155,7 +155,6 @@ static void __devexit hydra_remove(struct pci_dev *dev)
static struct pci_driver hydra_driver = {
- .owner = THIS_MODULE,
.name = "hydra_smbus",
.id_table = hydra_ids,
.probe = hydra_probe,
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 4f631950..ac3eafa 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -560,7 +560,6 @@ static void __devexit i801_remove(struct pci_dev *dev)
}
static struct pci_driver i801_driver = {
- .owner = THIS_MODULE,
.name = "i801_smbus",
.id_table = i801_ids,
.probe = i801_probe,
diff --git a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
index 52bc305..748be30 100644
--- a/drivers/i2c/busses/i2c-i810.c
+++ b/drivers/i2c/busses/i2c-i810.c
@@ -233,7 +233,6 @@ static void __devexit i810_remove(struct pci_dev *dev)
}
static struct pci_driver i810_driver = {
- .owner = THIS_MODULE,
.name = "i810_smbus",
.id_table = i810_ids,
.probe = i810_probe,
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index cfae4ad..1414851 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -405,10 +405,9 @@ static struct i2c_algorithm iop3xx_i2c_algo = {
};
static int
-iop3xx_i2c_remove(struct device *device)
+iop3xx_i2c_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(device);
- struct i2c_adapter *padapter = dev_get_drvdata(&pdev->dev);
+ struct i2c_adapter *padapter = platform_get_drvdata(pdev);
struct i2c_algo_iop3xx_data *adapter_data =
(struct i2c_algo_iop3xx_data *)padapter->algo_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -426,15 +425,14 @@ iop3xx_i2c_remove(struct device *device)
kfree(adapter_data);
kfree(padapter);
- dev_set_drvdata(&pdev->dev, NULL);
+ platform_set_drvdata(pdev, NULL);
return 0;
}
static int
-iop3xx_i2c_probe(struct device *dev)
+iop3xx_i2c_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
int ret;
struct i2c_adapter *new_adapter;
@@ -499,7 +497,7 @@ iop3xx_i2c_probe(struct device *dev)
iop3xx_i2c_set_slave_addr(adapter_data);
iop3xx_i2c_enable(adapter_data);
- dev_set_drvdata(&pdev->dev, new_adapter);
+ platform_set_drvdata(pdev, new_adapter);
new_adapter->algo_data = adapter_data;
i2c_add_adapter(new_adapter);
@@ -523,24 +521,25 @@ out:
}
-static struct device_driver iop3xx_i2c_driver = {
- .owner = THIS_MODULE,
- .name = "IOP3xx-I2C",
- .bus = &platform_bus_type,
+static struct platform_driver iop3xx_i2c_driver = {
.probe = iop3xx_i2c_probe,
- .remove = iop3xx_i2c_remove
+ .remove = iop3xx_i2c_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "IOP3xx-I2C",
+ },
};
static int __init
i2c_iop3xx_init (void)
{
- return driver_register(&iop3xx_i2c_driver);
+ return platform_driver_register(&iop3xx_i2c_driver);
}
static void __exit
i2c_iop3xx_exit (void)
{
- driver_unregister(&iop3xx_i2c_driver);
+ platform_driver_unregister(&iop3xx_i2c_driver);
return;
}
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index 64552a3..cef024a 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -86,12 +86,11 @@ struct ixp2000_i2c_data {
struct i2c_algo_bit_data algo_data;
};
-static int ixp2000_i2c_remove(struct device *dev)
+static int ixp2000_i2c_remove(struct platform_device *plat_dev)
{
- struct platform_device *plat_dev = to_platform_device(dev);
- struct ixp2000_i2c_data *drv_data = dev_get_drvdata(&plat_dev->dev);
+ struct ixp2000_i2c_data *drv_data = platform_get_drvdata(plat_dev);
- dev_set_drvdata(&plat_dev->dev, NULL);
+ platform_set_drvdata(plat_dev, NULL);
i2c_bit_del_bus(&drv_data->adapter);
@@ -100,10 +99,9 @@ static int ixp2000_i2c_remove(struct device *dev)
return 0;
}
-static int ixp2000_i2c_probe(struct device *dev)
+static int ixp2000_i2c_probe(struct platform_device *plat_dev)
{
int err;
- struct platform_device *plat_dev = to_platform_device(dev);
struct ixp2000_i2c_pins *gpio = plat_dev->dev.platform_data;
struct ixp2000_i2c_data *drv_data =
kzalloc(sizeof(struct ixp2000_i2c_data), GFP_KERNEL);
@@ -139,27 +137,28 @@ static int ixp2000_i2c_probe(struct device *dev)
return err;
}
- dev_set_drvdata(&plat_dev->dev, drv_data);
+ platform_set_drvdata(plat_dev, drv_data);
return 0;
}
-static struct device_driver ixp2000_i2c_driver = {
- .owner = THIS_MODULE,
- .name = "IXP2000-I2C",
- .bus = &platform_bus_type,
+static struct platform_driver ixp2000_i2c_driver = {
.probe = ixp2000_i2c_probe,
.remove = ixp2000_i2c_remove,
+ .driver = {
+ .name = "IXP2000-I2C",
+ .owner = THIS_MODULE,
+ },
};
static int __init ixp2000_i2c_init(void)
{
- return driver_register(&ixp2000_i2c_driver);
+ return platform_driver_register(&ixp2000_i2c_driver);
}
static void __exit ixp2000_i2c_exit(void)
{
- driver_unregister(&ixp2000_i2c_driver);
+ platform_driver_unregister(&ixp2000_i2c_driver);
}
module_init(ixp2000_i2c_init);
diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c
index cc652c3..f87220b 100644
--- a/drivers/i2c/busses/i2c-ixp4xx.c
+++ b/drivers/i2c/busses/i2c-ixp4xx.c
@@ -35,7 +35,7 @@
#include <asm/hardware.h> /* Pick up IXP4xx-specific bits */
-static struct device_driver ixp4xx_i2c_driver;
+static struct platform_driver ixp4xx_i2c_driver;
static inline int ixp4xx_scl_pin(void *data)
{
@@ -87,12 +87,11 @@ struct ixp4xx_i2c_data {
struct i2c_algo_bit_data algo_data;
};
-static int ixp4xx_i2c_remove(struct device *dev)
+static int ixp4xx_i2c_remove(struct platform_device *plat_dev)
{
- struct platform_device *plat_dev = to_platform_device(dev);
- struct ixp4xx_i2c_data *drv_data = dev_get_drvdata(&plat_dev->dev);
+ struct ixp4xx_i2c_data *drv_data = platform_get_drvdata(plat_dev);
- dev_set_drvdata(&plat_dev->dev, NULL);
+ platform_set_drvdata(plat_dev, NULL);
i2c_bit_del_bus(&drv_data->adapter);
@@ -101,10 +100,9 @@ static int ixp4xx_i2c_remove(struct device *dev)
return 0;
}
-static int ixp4xx_i2c_probe(struct device *dev)
+static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
{
int err;
- struct platform_device *plat_dev = to_platform_device(dev);
struct ixp4xx_i2c_pins *gpio = plat_dev->dev.platform_data;
struct ixp4xx_i2c_data *drv_data =
kzalloc(sizeof(struct ixp4xx_i2c_data), GFP_KERNEL);
@@ -130,7 +128,7 @@ static int ixp4xx_i2c_probe(struct device *dev)
drv_data->algo_data.timeout = 100;
drv_data->adapter.id = I2C_HW_B_IXP4XX;
- strlcpy(drv_data->adapter.name, ixp4xx_i2c_driver.name,
+ strlcpy(drv_data->adapter.name, ixp4xx_i2c_driver.driver.name,
I2C_NAME_SIZE);
drv_data->adapter.algo_data = &drv_data->algo_data;
@@ -142,33 +140,35 @@ static int ixp4xx_i2c_probe(struct device *dev)
gpio_line_set(gpio->sda_pin, 0);
if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) {
- printk(KERN_ERR "ERROR: Could not install %s\n", dev->bus_id);
+ printk(KERN_ERR "ERROR: Could not install %s\n",
+ plat_dev->dev.bus_id);
kfree(drv_data);
return err;
}
- dev_set_drvdata(&plat_dev->dev, drv_data);
+ platform_set_drvdata(plat_dev, drv_data);
return 0;
}
-static struct device_driver ixp4xx_i2c_driver = {
- .owner = THIS_MODULE,
- .name = "IXP4XX-I2C",
- .bus = &platform_bus_type,
+static struct platform_driver ixp4xx_i2c_driver = {
.probe = ixp4xx_i2c_probe,
.remove = ixp4xx_i2c_remove,
+ .driver = {
+ .name = "IXP4XX-I2C",
+ .owner = THIS_MODULE,
+ },
};
static int __init ixp4xx_i2c_init(void)
{
- return driver_register(&ixp4xx_i2c_driver);
+ return platform_driver_register(&ixp4xx_i2c_driver);
}
static void __exit ixp4xx_i2c_exit(void)
{
- driver_unregister(&ixp4xx_i2c_driver);
+ platform_driver_unregister(&ixp4xx_i2c_driver);
}
module_init(ixp4xx_i2c_init);
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 65b939a..5ccd338 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -288,11 +288,10 @@ static struct i2c_adapter mpc_ops = {
.retries = 1
};
-static int fsl_i2c_probe(struct device *device)
+static int fsl_i2c_probe(struct platform_device *pdev)
{
int result = 0;
struct mpc_i2c *i2c;
- struct platform_device *pdev = to_platform_device(device);
struct fsl_i2c_platform_data *pdata;
struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -323,7 +322,7 @@ static int fsl_i2c_probe(struct device *device)
}
mpc_i2c_setclock(i2c);
- dev_set_drvdata(device, i2c);
+ platform_set_drvdata(pdev, i2c);
i2c->adap = mpc_ops;
i2c_set_adapdata(&i2c->adap, i2c);
@@ -345,12 +344,12 @@ static int fsl_i2c_probe(struct device *device)
return result;
};
-static int fsl_i2c_remove(struct device *device)
+static int fsl_i2c_remove(struct platform_device *pdev)
{
- struct mpc_i2c *i2c = dev_get_drvdata(device);
+ struct mpc_i2c *i2c = platform_get_drvdata(pdev);
i2c_del_adapter(&i2c->adap);
- dev_set_drvdata(device, NULL);
+ platform_set_drvdata(pdev, NULL);
if (i2c->irq != 0)
free_irq(i2c->irq, i2c);
@@ -361,22 +360,23 @@ static int fsl_i2c_remove(struct device *device)
};
/* Structure for a device driver */
-static struct device_driver fsl_i2c_driver = {
- .owner = THIS_MODULE,
- .name = "fsl-i2c",
- .bus = &platform_bus_type,
+static struct platform_driver fsl_i2c_driver = {
.probe = fsl_i2c_probe,
.remove = fsl_i2c_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "fsl-i2c",
+ },
};
static int __init fsl_i2c_init(void)
{
- return driver_register(&fsl_i2c_driver);
+ return platform_driver_register(&fsl_i2c_driver);
}
static void __exit fsl_i2c_exit(void)
{
- driver_unregister(&fsl_i2c_driver);
+ platform_driver_unregister(&fsl_i2c_driver);
}
module_init(fsl_i2c_init);
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 6b48027..afd7634 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -492,11 +492,10 @@ mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data)
}
static int __devinit
-mv64xxx_i2c_probe(struct device *dev)
+mv64xxx_i2c_probe(struct platform_device *pd)
{
- struct platform_device *pd = to_platform_device(dev);
struct mv64xxx_i2c_data *drv_data;
- struct mv64xxx_i2c_pdata *pdata = dev->platform_data;
+ struct mv64xxx_i2c_pdata *pdata = pd->dev.platform_data;
int rc;
if ((pd->id != 0) || !pdata)
@@ -526,7 +525,7 @@ mv64xxx_i2c_probe(struct device *dev)
drv_data->adapter.class = I2C_CLASS_HWMON;
drv_data->adapter.timeout = pdata->timeout;
drv_data->adapter.retries = pdata->retries;
- dev_set_drvdata(dev, drv_data);
+ platform_set_drvdata(pd, drv_data);
i2c_set_adapdata(&drv_data->adapter, drv_data);
if (request_irq(drv_data->irq, mv64xxx_i2c_intr, 0,
@@ -555,9 +554,9 @@ mv64xxx_i2c_probe(struct device *dev)
}
static int __devexit
-mv64xxx_i2c_remove(struct device *dev)
+mv64xxx_i2c_remove(struct platform_device *dev)
{
- struct mv64xxx_i2c_data *drv_data = dev_get_drvdata(dev);
+ struct mv64xxx_i2c_data *drv_data = platform_get_drvdata(dev);
int rc;
rc = i2c_del_adapter(&drv_data->adapter);
@@ -568,24 +567,25 @@ mv64xxx_i2c_remove(struct device *dev)
return rc;
}
-static struct device_driver mv64xxx_i2c_driver = {
- .owner = THIS_MODULE,
- .name = MV64XXX_I2C_CTLR_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver mv64xxx_i2c_driver = {
.probe = mv64xxx_i2c_probe,
.remove = mv64xxx_i2c_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = MV64XXX_I2C_CTLR_NAME,
+ },
};
static int __init
mv64xxx_i2c_init(void)
{
- return driver_register(&mv64xxx_i2c_driver);
+ return platform_driver_register(&mv64xxx_i2c_driver);
}
static void __exit
mv64xxx_i2c_exit(void)
{
- driver_unregister(&mv64xxx_i2c_driver);
+ platform_driver_unregister(&mv64xxx_i2c_driver);
}
module_init(mv64xxx_i2c_init);
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index fd26036..4d18e6e5 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -347,7 +347,6 @@ static void __devexit nforce2_remove(struct pci_dev *dev)
}
static struct pci_driver nforce2_driver = {
- .owner = THIS_MODULE,
.name = "nForce2_smbus",
.id_table = nforce2_ids,
.probe = nforce2_probe,
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 7d63eec..692f473 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -462,7 +462,6 @@ static void __devexit piix4_remove(struct pci_dev *dev)
}
static struct pci_driver piix4_driver = {
- .owner = THIS_MODULE,
.name = "piix4_smbus",
.id_table = piix4_ids,
.probe = piix4_probe,
diff --git a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
index 42cb1d8..9479525 100644
--- a/drivers/i2c/busses/i2c-prosavage.c
+++ b/drivers/i2c/busses/i2c-prosavage.c
@@ -301,7 +301,6 @@ static struct pci_device_id prosavage_pci_tbl[] = {
MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl);
static struct pci_driver prosavage_driver = {
- .owner = THIS_MODULE,
.name = "prosavage_smbus",
.id_table = prosavage_pci_tbl,
.probe = prosavage_probe,
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 67ccbea..70f7ab8 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -936,10 +936,10 @@ static struct pxa_i2c i2c_pxa = {
},
};
-static int i2c_pxa_probe(struct device *dev)
+static int i2c_pxa_probe(struct platform_device *dev)
{
struct pxa_i2c *i2c = &i2c_pxa;
- struct i2c_pxa_platform_data *plat = dev->platform_data;
+ struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
int ret;
#ifdef CONFIG_PXA27x
@@ -968,7 +968,7 @@ static int i2c_pxa_probe(struct device *dev)
i2c_pxa_reset(i2c);
i2c->adap.algo_data = i2c;
- i2c->adap.dev.parent = dev;
+ i2c->adap.dev.parent = &dev->dev;
ret = i2c_add_adapter(&i2c->adap);
if (ret < 0) {
@@ -976,7 +976,7 @@ static int i2c_pxa_probe(struct device *dev)
goto err_irq;
}
- dev_set_drvdata(dev, i2c);
+ platform_set_drvdata(dev, i2c);
#ifdef CONFIG_I2C_PXA_SLAVE
printk(KERN_INFO "I2C: %s: PXA I2C adapter, slave address %d\n",
@@ -993,11 +993,11 @@ static int i2c_pxa_probe(struct device *dev)
return ret;
}
-static int i2c_pxa_remove(struct device *dev)
+static int i2c_pxa_remove(struct platform_device *dev)
{
- struct pxa_i2c *i2c = dev_get_drvdata(dev);
+ struct pxa_i2c *i2c = platform_get_drvdata(dev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
i2c_del_adapter(&i2c->adap);
free_irq(IRQ_I2C, i2c);
@@ -1006,21 +1006,22 @@ static int i2c_pxa_remove(struct device *dev)
return 0;
}
-static struct device_driver i2c_pxa_driver = {
- .name = "pxa2xx-i2c",
- .bus = &platform_bus_type,
+static struct platform_driver i2c_pxa_driver = {
.probe = i2c_pxa_probe,
.remove = i2c_pxa_remove,
+ .driver = {
+ .name = "pxa2xx-i2c",
+ },
};
static int __init i2c_adap_pxa_init(void)
{
- return driver_register(&i2c_pxa_driver);
+ return platform_driver_register(&i2c_pxa_driver);
}
static void i2c_adap_pxa_exit(void)
{
- return driver_unregister(&i2c_pxa_driver);
+ return platform_driver_unregister(&i2c_pxa_driver);
}
module_init(i2c_adap_pxa_init);
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 1b58226..58cfd31 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -760,24 +760,23 @@ static void s3c24xx_i2c_free(struct s3c24xx_i2c *i2c)
* called by the bus driver when a suitable device is found
*/
-static int s3c24xx_i2c_probe(struct device *dev)
+static int s3c24xx_i2c_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct s3c24xx_i2c *i2c = &s3c24xx_i2c;
struct resource *res;
int ret;
/* find the clock and enable it */
- i2c->dev = dev;
- i2c->clk = clk_get(dev, "i2c");
+ i2c->dev = &pdev->dev;
+ i2c->clk = clk_get(&pdev->dev, "i2c");
if (IS_ERR(i2c->clk)) {
- dev_err(dev, "cannot get clock\n");
+ dev_err(&pdev->dev, "cannot get clock\n");
ret = -ENOENT;
goto out;
}
- dev_dbg(dev, "clock source %p\n", i2c->clk);
+ dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
clk_use(i2c->clk);
clk_enable(i2c->clk);
@@ -786,7 +785,7 @@ static int s3c24xx_i2c_probe(struct device *dev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
- dev_err(dev, "cannot find IO resource\n");
+ dev_err(&pdev->dev, "cannot find IO resource\n");
ret = -ENOENT;
goto out;
}
@@ -795,7 +794,7 @@ static int s3c24xx_i2c_probe(struct device *dev)
pdev->name);
if (i2c->ioarea == NULL) {
- dev_err(dev, "cannot request IO\n");
+ dev_err(&pdev->dev, "cannot request IO\n");
ret = -ENXIO;
goto out;
}
@@ -803,17 +802,17 @@ static int s3c24xx_i2c_probe(struct device *dev)
i2c->regs = ioremap(res->start, (res->end-res->start)+1);
if (i2c->regs == NULL) {
- dev_err(dev, "cannot map IO\n");
+ dev_err(&pdev->dev, "cannot map IO\n");
ret = -ENXIO;
goto out;
}
- dev_dbg(dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res);
+ dev_dbg(&pdev->dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res);
/* setup info block for the i2c core */
i2c->adap.algo_data = i2c;
- i2c->adap.dev.parent = dev;
+ i2c->adap.dev.parent = &pdev->dev;
/* initialise the i2c controller */
@@ -827,7 +826,7 @@ static int s3c24xx_i2c_probe(struct device *dev)
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (res == NULL) {
- dev_err(dev, "cannot find IRQ\n");
+ dev_err(&pdev->dev, "cannot find IRQ\n");
ret = -ENOENT;
goto out;
}
@@ -836,23 +835,23 @@ static int s3c24xx_i2c_probe(struct device *dev)
pdev->name, i2c);
if (ret != 0) {
- dev_err(dev, "cannot claim IRQ\n");
+ dev_err(&pdev->dev, "cannot claim IRQ\n");
goto out;
}
i2c->irq = res;
- dev_dbg(dev, "irq resource %p (%ld)\n", res, res->start);
+ dev_dbg(&pdev->dev, "irq resource %p (%ld)\n", res, res->start);
ret = i2c_add_adapter(&i2c->adap);
if (ret < 0) {
- dev_err(dev, "failed to add bus to i2c core\n");
+ dev_err(&pdev->dev, "failed to add bus to i2c core\n");
goto out;
}
- dev_set_drvdata(dev, i2c);
+ platform_set_drvdata(pdev, i2c);
- dev_info(dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id);
+ dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id);
out:
if (ret < 0)
@@ -866,22 +865,22 @@ static int s3c24xx_i2c_probe(struct device *dev)
* called when device is removed from the bus
*/
-static int s3c24xx_i2c_remove(struct device *dev)
+static int s3c24xx_i2c_remove(struct platform_device *pdev)
{
- struct s3c24xx_i2c *i2c = dev_get_drvdata(dev);
+ struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
if (i2c != NULL) {
s3c24xx_i2c_free(i2c);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
}
return 0;
}
#ifdef CONFIG_PM
-static int s3c24xx_i2c_resume(struct device *dev)
+static int s3c24xx_i2c_resume(struct platform_device *dev)
{
- struct s3c24xx_i2c *i2c = dev_get_drvdata(dev);
+ struct s3c24xx_i2c *i2c = platform_get_drvdata(dev);
if (i2c != NULL)
s3c24xx_i2c_init(i2c);
@@ -895,33 +894,35 @@ static int s3c24xx_i2c_resume(struct device *dev)
/* device driver for platform bus bits */
-static struct device_driver s3c2410_i2c_driver = {
- .owner = THIS_MODULE,
- .name = "s3c2410-i2c",
- .bus = &platform_bus_type,
+static struct platform_driver s3c2410_i2c_driver = {
.probe = s3c24xx_i2c_probe,
.remove = s3c24xx_i2c_remove,
.resume = s3c24xx_i2c_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s3c2410-i2c",
+ },
};
-static struct device_driver s3c2440_i2c_driver = {
- .owner = THIS_MODULE,
- .name = "s3c2440-i2c",
- .bus = &platform_bus_type,
+static struct platform_driver s3c2440_i2c_driver = {
.probe = s3c24xx_i2c_probe,
.remove = s3c24xx_i2c_remove,
.resume = s3c24xx_i2c_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s3c2440-i2c",
+ },
};
static int __init i2c_adap_s3c_init(void)
{
int ret;
- ret = driver_register(&s3c2410_i2c_driver);
+ ret = platform_driver_register(&s3c2410_i2c_driver);
if (ret == 0) {
- ret = driver_register(&s3c2440_i2c_driver);
+ ret = platform_driver_register(&s3c2440_i2c_driver);
if (ret)
- driver_unregister(&s3c2410_i2c_driver);
+ platform_driver_unregister(&s3c2410_i2c_driver);
}
return ret;
@@ -929,8 +930,8 @@ static int __init i2c_adap_s3c_init(void)
static void __exit i2c_adap_s3c_exit(void)
{
- driver_unregister(&s3c2410_i2c_driver);
- driver_unregister(&s3c2440_i2c_driver);
+ platform_driver_unregister(&s3c2410_i2c_driver);
+ platform_driver_unregister(&s3c2440_i2c_driver);
}
module_init(i2c_adap_s3c_init);
diff --git a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
index aebe87b..0c85182 100644
--- a/drivers/i2c/busses/i2c-savage4.c
+++ b/drivers/i2c/busses/i2c-savage4.c
@@ -179,7 +179,6 @@ static void __devexit savage4_remove(struct pci_dev *dev)
}
static struct pci_driver savage4_driver = {
- .owner = THIS_MODULE,
.name = "savage4_smbus",
.id_table = savage4_ids,
.probe = savage4_probe,
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index 3ad27c3..b57ab74d 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -398,7 +398,6 @@ static void __devexit sis5595_remove(struct pci_dev *dev)
}
static struct pci_driver sis5595_driver = {
- .owner = THIS_MODULE,
.name = "sis5595_smbus",
.id_table = sis5595_ids,
.probe = sis5595_probe,
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
index 7f49e5f..acb75e2 100644
--- a/drivers/i2c/busses/i2c-sis630.c
+++ b/drivers/i2c/busses/i2c-sis630.c
@@ -496,7 +496,6 @@ static void __devexit sis630_remove(struct pci_dev *dev)
static struct pci_driver sis630_driver = {
- .owner = THIS_MODULE,
.name = "sis630_smbus",
.id_table = sis630_ids,
.probe = sis630_probe,
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
index 6a134c0..3024907 100644
--- a/drivers/i2c/busses/i2c-sis96x.c
+++ b/drivers/i2c/busses/i2c-sis96x.c
@@ -329,7 +329,6 @@ static void __devexit sis96x_remove(struct pci_dev *dev)
}
static struct pci_driver sis96x_driver = {
- .owner = THIS_MODULE,
.name = "sis96x_smbus",
.id_table = sis96x_ids,
.probe = sis96x_probe,
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
index 544a38e..484bbac 100644
--- a/drivers/i2c/busses/i2c-via.c
+++ b/drivers/i2c/busses/i2c-via.c
@@ -159,7 +159,6 @@ static void __devexit vt586b_remove(struct pci_dev *dev)
static struct pci_driver vt586b_driver = {
- .owner = THIS_MODULE,
.name = "vt586b_smbus",
.id_table = vt586b_ids,
.probe = vt586b_probe,
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index a2237d4..47e52bf 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -440,7 +440,6 @@ static struct pci_device_id vt596_ids[] = {
MODULE_DEVICE_TABLE(pci, vt596_ids);
static struct pci_driver vt596_driver = {
- .owner = THIS_MODULE,
.name = "vt596_smbus",
.id_table = vt596_ids,
.probe = vt596_probe,
diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
index 650c3eb..b675773 100644
--- a/drivers/i2c/busses/i2c-voodoo3.c
+++ b/drivers/i2c/busses/i2c-voodoo3.c
@@ -225,7 +225,6 @@ static void __devexit voodoo3_remove(struct pci_dev *dev)
}
static struct pci_driver voodoo3_driver = {
- .owner = THIS_MODULE,
.name = "voodoo3_smbus",
.id_table = voodoo3_ids,
.probe = voodoo3_probe,
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
index 9dbb72f..d2a100d 100644
--- a/drivers/i2c/chips/isp1301_omap.c
+++ b/drivers/i2c/chips/isp1301_omap.c
@@ -873,26 +873,27 @@ static int otg_init(struct isp1301 *isp)
return 0;
}
-static int otg_probe(struct device *dev)
+static int otg_probe(struct platform_device *dev)
{
// struct omap_usb_config *config = dev->platform_data;
- otg_dev = to_platform_device(dev);
+ otg_dev = dev;
return 0;
}
-static int otg_remove(struct device *dev)
+static int otg_remove(struct platform_device *dev)
{
otg_dev = 0;
return 0;
}
-struct device_driver omap_otg_driver = {
- .owner = THIS_MODULE,
- .name = "omap_otg",
- .bus = &platform_bus_type,
+struct platform_driver omap_otg_driver = {
.probe = otg_probe,
- .remove = otg_remove,
+ .remove = otg_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "omap_otg",
+ },
};
static int otg_bind(struct isp1301 *isp)
@@ -902,7 +903,7 @@ static int otg_bind(struct isp1301 *isp)
if (otg_dev)
return -EBUSY;
- status = driver_register(&omap_otg_driver);
+ status = platform_driver_register(&omap_otg_driver);
if (status < 0)
return status;
@@ -913,7 +914,7 @@ static int otg_bind(struct isp1301 *isp)
status = -ENODEV;
if (status < 0)
- driver_unregister(&omap_otg_driver);
+ platform_driver_unregister(&omap_otg_driver);
return status;
}
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 42e5b81..31e649a 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -625,7 +625,7 @@ config BLK_DEV_NS87415
tristate "NS87415 chipset support"
help
This driver adds detection and support for the NS87415 chip
- (used in SPARC64, among others).
+ (used mainly on SPARC64 and PA-RISC machines).
Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>.
@@ -787,6 +787,10 @@ config BLK_DEV_IDE_PMAC_BLINK
This option enables the use of the sleep LED as a hard drive
activity LED.
+config BLK_DEV_IDE_SWARM
+ tristate "IDE for Sibyte evaluation boards"
+ depends on SIBYTE_SB1xxx_SOC
+
config BLK_DEV_IDE_AU1XXX
bool "IDE for AMD Alchemy Au1200"
depends on SOC_AU1200
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index cca9c07..569fae7 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -48,6 +48,6 @@ obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o
obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o
-obj-$(CONFIG_BLK_DEV_IDE) += legacy/ arm/
+obj-$(CONFIG_BLK_DEV_IDE) += legacy/ arm/ mips/
obj-$(CONFIG_BLK_DEV_HD) += legacy/
obj-$(CONFIG_ETRAX_IDE) += cris/
diff --git a/drivers/ide/mips/Makefile b/drivers/ide/mips/Makefile
new file mode 100644
index 0000000..578e52a
--- /dev/null
+++ b/drivers/ide/mips/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_BLK_DEV_IDE_SWARM) += swarm.o
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
new file mode 100644
index 0000000..66f6064
--- /dev/null
+++ b/drivers/ide/mips/swarm.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com
+ * Copyright (C) 2004 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Derived loosely from ide-pmac.c, so:
+ * Copyright (C) 1998 Paul Mackerras.
+ * Copyright (C) 1995-1998 Mark Lord
+ */
+
+/*
+ * Boards with SiByte processors so far have supported IDE devices via
+ * the Generic Bus, PCI bus, and built-in PCMCIA interface. In all
+ * cases, byte-swapping must be avoided for these devices (whereas
+ * other PCI devices, for example, will require swapping). Any
+ * SiByte-targetted kernel including IDE support will include this
+ * file. Probing of a Generic Bus for an IDE device is controlled by
+ * the definition of "SIBYTE_HAVE_IDE", which is provided by
+ * <asm/sibyte/board.h> for Broadcom boards.
+ */
+
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+
+#include <asm/sibyte/board.h>
+#include <asm/sibyte/sb1250_genbus.h>
+#include <asm/sibyte/sb1250_regs.h>
+
+#define DRV_NAME "ide-swarm"
+
+static char swarm_ide_string[] = DRV_NAME;
+
+static struct resource swarm_ide_resource = {
+ .name = "SWARM GenBus IDE",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device *swarm_ide_dev;
+
+/*
+ * swarm_ide_probe - if the board header indicates the existence of
+ * Generic Bus IDE, allocate a HWIF for it.
+ */
+static int __devinit swarm_ide_probe(struct device *dev)
+{
+ ide_hwif_t *hwif;
+ u8 __iomem *base;
+ phys_t offset, size;
+ int i;
+
+ if (!SIBYTE_HAVE_IDE)
+ return -ENODEV;
+
+ /* Find an empty slot. */
+ for (i = 0; i < MAX_HWIFS; i++)
+ if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET])
+ break;
+ if (i >= MAX_HWIFS) {
+ printk(KERN_ERR DRV_NAME ": no free slot for interface\n");
+ return -ENOMEM;
+ }
+
+ hwif = ide_hwifs + i;
+
+ base = ioremap(A_IO_EXT_BASE, 0x800);
+ offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS));
+ size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS));
+ iounmap(base);
+
+ offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE;
+ size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE;
+ if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) {
+ printk(KERN_INFO DRV_NAME
+ ": IDE interface at GenBus disabled\n");
+ return -EBUSY;
+ }
+
+ printk(KERN_INFO DRV_NAME ": IDE interface at GenBus slot %i\n",
+ IDE_CS);
+
+ swarm_ide_resource.start = offset;
+ swarm_ide_resource.end = offset + size - 1;
+ if (request_resource(&iomem_resource, &swarm_ide_resource)) {
+ printk(KERN_ERR DRV_NAME
+ ": can't request I/O memory resource\n");
+ return -EBUSY;
+ }
+
+ base = ioremap(offset, size);
+
+ /* Setup MMIO ops. */
+ default_hwif_mmiops(hwif);
+ /* Prevent resource map manipulation. */
+ hwif->mmio = 2;
+ hwif->noprobe = 0;
+
+ for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
+ hwif->hw.io_ports[i] =
+ (unsigned long)(base + ((0x1f0 + i) << 5));
+ hwif->hw.io_ports[IDE_CONTROL_OFFSET] =
+ (unsigned long)(base + (0x3f6 << 5));
+ hwif->hw.irq = K_INT_GB_IDE;
+
+ memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+ hwif->irq = hwif->hw.irq;
+
+ dev_set_drvdata(dev, hwif);
+
+ return 0;
+}
+
+static struct device_driver swarm_ide_driver = {
+ .name = swarm_ide_string,
+ .bus = &platform_bus_type,
+ .probe = swarm_ide_probe,
+};
+
+static void swarm_ide_platform_release(struct device *device)
+{
+ struct platform_device *pldev;
+
+ /* free device */
+ pldev = to_platform_device(device);
+ kfree(pldev);
+}
+
+static int __devinit swarm_ide_init_module(void)
+{
+ struct platform_device *pldev;
+ int err;
+
+ printk(KERN_INFO "SWARM IDE driver\n");
+
+ if (driver_register(&swarm_ide_driver)) {
+ printk(KERN_ERR "Driver registration failed\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ if (!(pldev = kmalloc(sizeof (*pldev), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto out_unregister_driver;
+ }
+
+ memset (pldev, 0, sizeof (*pldev));
+ pldev->name = swarm_ide_string;
+ pldev->id = 0;
+ pldev->dev.release = swarm_ide_platform_release;
+
+ if (platform_device_register(pldev)) {
+ err = -ENODEV;
+ goto out_free_pldev;
+ }
+
+ if (!pldev->dev.driver) {
+ /*
+ * The driver was not bound to this device, there was
+ * no hardware at this address. Unregister it, as the
+ * release fuction will take care of freeing the
+ * allocated structure
+ */
+ platform_device_unregister (pldev);
+ }
+
+ swarm_ide_dev = pldev;
+
+ return 0;
+
+out_free_pldev:
+ kfree(pldev);
+
+out_unregister_driver:
+ driver_unregister(&swarm_ide_driver);
+out:
+ return err;
+}
+
+module_init(swarm_ide_init_module);
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index ea0806c..8a5c7b2 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -399,34 +399,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
return dev->irq;
}
-static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
-{
- unsigned int rev;
- u8 dma_state;
-
- DBG(("init_dma_sl82c105(hwif: ide%d, dma_base: 0x%08x)\n", hwif->index, dma_base));
-
- hwif->autodma = 0;
-
- if (!dma_base)
- return;
-
- dma_state = hwif->INB(dma_base + 2);
- rev = sl82c105_bridge_revision(hwif->pci_dev);
- if (rev <= 5) {
- printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
- hwif->name, rev);
- dma_state &= ~0x60;
- } else {
- dma_state |= 0x60;
- if (!noautodma)
- hwif->autodma = 1;
- }
- hwif->OUTB(dma_state, dma_base + 2);
-
- ide_setup_dma(hwif, dma_base, 8);
-}
-
/*
* Initialise the chip
*/
@@ -434,6 +406,8 @@ static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base
static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
+ unsigned int rev;
+ u8 dma_state;
u32 val;
DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
@@ -455,33 +429,54 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
pci_read_config_dword(dev, 0x40, &val);
*((u32 *)&hwif->hwif_data) = val;
+ hwif->atapi_dma = 0;
+ hwif->mwdma_mask = 0;
+ hwif->swdma_mask = 0;
+ hwif->autodma = 0;
+
if (!hwif->dma_base)
return;
- hwif->atapi_dma = 1;
- hwif->mwdma_mask = 0x07;
- hwif->swdma_mask = 0x07;
-
+ dma_state = hwif->INB(hwif->dma_base + 2) & ~0x60;
+ rev = sl82c105_bridge_revision(hwif->pci_dev);
+ if (rev <= 5) {
+ /*
+ * Never ever EVER under any circumstances enable
+ * DMA when the bridge is this old.
+ */
+ printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
+ hwif->name, rev);
+ } else {
#ifdef CONFIG_BLK_DEV_IDEDMA
- hwif->ide_dma_check = &sl82c105_check_drive;
- hwif->ide_dma_on = &sl82c105_ide_dma_on;
- hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
- hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
- hwif->dma_start = &sl82c105_ide_dma_start;
- hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
+ dma_state |= 0x60;
+
+ hwif->atapi_dma = 1;
+ hwif->mwdma_mask = 0x07;
+ hwif->swdma_mask = 0x07;
+
+ hwif->ide_dma_check = &sl82c105_check_drive;
+ hwif->ide_dma_on = &sl82c105_ide_dma_on;
+ hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
+ hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
+ hwif->dma_start = &sl82c105_ide_dma_start;
+ hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
+
+ if (!noautodma)
+ hwif->autodma = 1;
+ hwif->drives[0].autodma = hwif->autodma;
+ hwif->drives[1].autodma = hwif->autodma;
+
+ if (hwif->mate)
+ hwif->serialized = hwif->mate->serialized = 1;
#endif /* CONFIG_BLK_DEV_IDEDMA */
+ }
+ hwif->OUTB(dma_state, hwif->dma_base + 2);
}
static ide_pci_device_t sl82c105_chipset __devinitdata = {
.name = "W82C105",
.init_chipset = init_chipset_sl82c105,
.init_hwif = init_hwif_sl82c105,
- .init_dma = init_dma_sl82c105,
.channels = 2,
.autodma = NOAUTODMA,
.enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index b3e65a6..136911a 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1667,11 +1667,16 @@ static struct macio_driver pmac_ide_macio_driver =
};
static struct pci_device_id pmac_ide_pci_match[] = {
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
};
static struct pci_driver pmac_ide_pci_driver = {
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 18ed776..d4f2111 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -787,8 +787,9 @@ static int pre_init = 1; /* Before first ordered IDE scan */
static LIST_HEAD(ide_pci_drivers);
/*
- * ide_register_pci_driver - attach IDE driver
+ * __ide_register_pci_driver - attach IDE driver
* @driver: pci driver
+ * @module: owner module of the driver
*
* Registers a driver with the IDE layer. The IDE layer arranges that
* boot time setup is done in the expected device order and then
@@ -801,15 +802,16 @@ static LIST_HEAD(ide_pci_drivers);
* Returns are the same as for pci_register_driver
*/
-int ide_pci_register_driver(struct pci_driver *driver)
+int __ide_pci_register_driver(struct pci_driver *driver, struct module *module)
{
if(!pre_init)
- return pci_module_init(driver);
+ return __pci_register_driver(driver, module);
+ driver->driver.owner = module;
list_add_tail(&driver->node, &ide_pci_drivers);
return 0;
}
-EXPORT_SYMBOL_GPL(ide_pci_register_driver);
+EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
/**
* ide_unregister_pci_driver - unregister an IDE driver
@@ -897,6 +899,6 @@ void __init ide_scan_pcibus (int scan_direction)
{
list_del(l);
d = list_entry(l, struct pci_driver, node);
- pci_register_driver(d);
+ __pci_register_driver(d, d->driver.owner);
}
}
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 147f248..6f94b25 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -1198,7 +1198,6 @@ MODULE_DEVICE_TABLE(pci, mthca_pci_table);
static struct pci_driver mthca_driver = {
.name = DRV_NAME,
- .owner = THIS_MODULE,
.id_table = mthca_pci_table,
.probe = mthca_init_one,
.remove = __devexit_p(mthca_remove_one)
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index d00d14b..64672d4 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -259,17 +259,17 @@ static void corgikbd_hinge_timer(unsigned long data)
}
#ifdef CONFIG_PM
-static int corgikbd_suspend(struct device *dev, pm_message_t state)
+static int corgikbd_suspend(struct platform_device *dev, pm_message_t state)
{
- struct corgikbd *corgikbd = dev_get_drvdata(dev);
+ struct corgikbd *corgikbd = platform_get_drvdata(dev);
corgikbd->suspended = 1;
return 0;
}
-static int corgikbd_resume(struct device *dev)
+static int corgikbd_resume(struct platform_device *dev)
{
- struct corgikbd *corgikbd = dev_get_drvdata(dev);
+ struct corgikbd *corgikbd = platform_get_drvdata(dev);
/* Upon resume, ignore the suspend key for a short while */
corgikbd->suspend_jiffies=jiffies;
@@ -282,7 +282,7 @@ static int corgikbd_resume(struct device *dev)
#define corgikbd_resume NULL
#endif
-static int __init corgikbd_probe(struct device *dev)
+static int __init corgikbd_probe(struct platform_device *pdev)
{
struct corgikbd *corgikbd;
struct input_dev *input_dev;
@@ -296,7 +296,7 @@ static int __init corgikbd_probe(struct device *dev)
return -ENOMEM;
}
- dev_set_drvdata(dev, corgikbd);
+ platform_set_drvdata(pdev, corgikbd);
corgikbd->input = input_dev;
spin_lock_init(&corgikbd->lock);
@@ -321,7 +321,7 @@ static int __init corgikbd_probe(struct device *dev)
input_dev->id.vendor = 0x0001;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
- input_dev->cdev.dev = dev;
+ input_dev->cdev.dev = &pdev->dev;
input_dev->private = corgikbd;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
@@ -356,10 +356,10 @@ static int __init corgikbd_probe(struct device *dev)
return 0;
}
-static int corgikbd_remove(struct device *dev)
+static int corgikbd_remove(struct platform_device *pdev)
{
int i;
- struct corgikbd *corgikbd = dev_get_drvdata(dev);
+ struct corgikbd *corgikbd = platform_get_drvdata(pdev);
for (i = 0; i < CORGI_KEY_SENSE_NUM; i++)
free_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd);
@@ -374,23 +374,24 @@ static int corgikbd_remove(struct device *dev)
return 0;
}
-static struct device_driver corgikbd_driver = {
- .name = "corgi-keyboard",
- .bus = &platform_bus_type,
+static struct platform_driver corgikbd_driver = {
.probe = corgikbd_probe,
.remove = corgikbd_remove,
.suspend = corgikbd_suspend,
.resume = corgikbd_resume,
+ .driver = {
+ .name = "corgi-keyboard",
+ },
};
static int __devinit corgikbd_init(void)
{
- return driver_register(&corgikbd_driver);
+ return platform_driver_register(&corgikbd_driver);
}
static void __exit corgikbd_exit(void)
{
- driver_unregister(&corgikbd_driver);
+ platform_driver_unregister(&corgikbd_driver);
}
module_init(corgikbd_init);
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index 0fa38a5..6a15fe3 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -309,10 +309,10 @@ static void spitzkbd_hinge_timer(unsigned long data)
}
#ifdef CONFIG_PM
-static int spitzkbd_suspend(struct device *dev, pm_message_t state)
+static int spitzkbd_suspend(struct platform_device *dev, pm_message_t state)
{
int i;
- struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+ struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
spitzkbd->suspended = 1;
/* Set Strobe lines as inputs - *except* strobe line 0 leave this
@@ -323,10 +323,10 @@ static int spitzkbd_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int spitzkbd_resume(struct device *dev)
+static int spitzkbd_resume(struct platform_device *dev)
{
int i;
- struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+ struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
@@ -342,7 +342,7 @@ static int spitzkbd_resume(struct device *dev)
#define spitzkbd_resume NULL
#endif
-static int __init spitzkbd_probe(struct device *dev)
+static int __init spitzkbd_probe(struct platform_device *dev)
{
struct spitzkbd *spitzkbd;
struct input_dev *input_dev;
@@ -358,7 +358,7 @@ static int __init spitzkbd_probe(struct device *dev)
return -ENOMEM;
}
- dev_set_drvdata(dev, spitzkbd);
+ platform_set_drvdata(dev, spitzkbd);
strcpy(spitzkbd->phys, "spitzkbd/input0");
spin_lock_init(&spitzkbd->lock);
@@ -380,7 +380,7 @@ static int __init spitzkbd_probe(struct device *dev)
input_dev->private = spitzkbd;
input_dev->name = "Spitz Keyboard";
input_dev->phys = spitzkbd->phys;
- input_dev->cdev.dev = dev;
+ input_dev->cdev.dev = &dev->dev;
input_dev->id.bustype = BUS_HOST;
input_dev->id.vendor = 0x0001;
@@ -437,10 +437,10 @@ static int __init spitzkbd_probe(struct device *dev)
return 0;
}
-static int spitzkbd_remove(struct device *dev)
+static int spitzkbd_remove(struct platform_device *dev)
{
int i;
- struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+ struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++)
free_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd);
@@ -460,23 +460,24 @@ static int spitzkbd_remove(struct device *dev)
return 0;
}
-static struct device_driver spitzkbd_driver = {
- .name = "spitz-keyboard",
- .bus = &platform_bus_type,
+static struct platform_driver spitzkbd_driver = {
.probe = spitzkbd_probe,
.remove = spitzkbd_remove,
.suspend = spitzkbd_suspend,
.resume = spitzkbd_resume,
+ .driver = {
+ .name = "spitz-keyboard",
+ },
};
static int __devinit spitzkbd_init(void)
{
- return driver_register(&spitzkbd_driver);
+ return platform_driver_register(&spitzkbd_driver);
}
static void __exit spitzkbd_exit(void)
{
- driver_unregister(&spitzkbd_driver);
+ platform_driver_unregister(&spitzkbd_driver);
}
module_init(spitzkbd_init);
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 01e1864..ac86c1d 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -912,7 +912,7 @@ static long i8042_panic_blink(long count)
* Here we try to restore the original BIOS settings
*/
-static int i8042_suspend(struct device *dev, pm_message_t state)
+static int i8042_suspend(struct platform_device *dev, pm_message_t state)
{
del_timer_sync(&i8042_timer);
i8042_controller_reset();
@@ -925,7 +925,7 @@ static int i8042_suspend(struct device *dev, pm_message_t state)
* Here we try to reset everything back to a state in which suspended
*/
-static int i8042_resume(struct device *dev)
+static int i8042_resume(struct platform_device *dev)
{
int i;
@@ -964,17 +964,18 @@ static int i8042_resume(struct device *dev)
* because otherwise BIOSes will be confused.
*/
-static void i8042_shutdown(struct device *dev)
+static void i8042_shutdown(struct platform_device *dev)
{
i8042_controller_cleanup();
}
-static struct device_driver i8042_driver = {
- .name = "i8042",
- .bus = &platform_bus_type,
+static struct platform_driver i8042_driver = {
.suspend = i8042_suspend,
.resume = i8042_resume,
.shutdown = i8042_shutdown,
+ .driver = {
+ .name = "i8042",
+ },
};
static int __init i8042_create_kbd_port(void)
@@ -1078,7 +1079,7 @@ static int __init i8042_init(void)
goto err_platform_exit;
}
- err = driver_register(&i8042_driver);
+ err = platform_driver_register(&i8042_driver);
if (err)
goto err_controller_cleanup;
@@ -1126,7 +1127,7 @@ static int __init i8042_init(void)
err_unregister_device:
platform_device_unregister(i8042_platform_device);
err_unregister_driver:
- driver_unregister(&i8042_driver);
+ platform_driver_unregister(&i8042_driver);
err_controller_cleanup:
i8042_controller_cleanup();
err_platform_exit:
@@ -1148,7 +1149,7 @@ static void __exit i8042_exit(void)
del_timer_sync(&i8042_timer);
platform_device_unregister(i8042_platform_device);
- driver_unregister(&i8042_driver);
+ platform_driver_unregister(&i8042_driver);
i8042_platform_exit();
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
index 52c4925..a3bd115 100644
--- a/drivers/input/serio/rpckbd.c
+++ b/drivers/input/serio/rpckbd.c
@@ -107,7 +107,7 @@ static void rpckbd_close(struct serio *port)
* Allocate and initialize serio structure for subsequent registration
* with serio core.
*/
-static int __devinit rpckbd_probe(struct device *dev)
+static int __devinit rpckbd_probe(struct platform_device *dev)
{
struct serio *serio;
@@ -120,37 +120,38 @@ static int __devinit rpckbd_probe(struct device *dev)
serio->write = rpckbd_write;
serio->open = rpckbd_open;
serio->close = rpckbd_close;
- serio->dev.parent = dev;
+ serio->dev.parent = &dev->dev;
strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
- dev_set_drvdata(dev, serio);
+ platform_set_drvdata(dev, serio);
serio_register_port(serio);
return 0;
}
-static int __devexit rpckbd_remove(struct device *dev)
+static int __devexit rpckbd_remove(struct platform_device *dev)
{
- struct serio *serio = dev_get_drvdata(dev);
+ struct serio *serio = platform_get_drvdata(dev);
serio_unregister_port(serio);
return 0;
}
-static struct device_driver rpckbd_driver = {
- .name = "kart",
- .bus = &platform_bus_type,
+static struct platform_driver rpckbd_driver = {
.probe = rpckbd_probe,
.remove = __devexit_p(rpckbd_remove),
+ .driver = {
+ .name = "kart",
+ },
};
static int __init rpckbd_init(void)
{
- return driver_register(&rpckbd_driver);
+ return platform_driver_register(&rpckbd_driver);
}
static void __exit rpckbd_exit(void)
{
- driver_unregister(&rpckbd_driver);
+ platform_driver_unregister(&rpckbd_driver);
}
module_init(rpckbd_init);
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index 15e88ee..1042987 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -231,9 +231,9 @@ static irqreturn_t ts_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
#ifdef CONFIG_PM
-static int corgits_suspend(struct device *dev, pm_message_t state)
+static int corgits_suspend(struct platform_device *dev, pm_message_t state)
{
- struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
+ struct corgi_ts *corgi_ts = platform_get_drvdata(dev);
if (corgi_ts->pendown) {
del_timer_sync(&corgi_ts->timer);
@@ -248,9 +248,9 @@ static int corgits_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int corgits_resume(struct device *dev)
+static int corgits_resume(struct platform_device *dev)
{
- struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
+ struct corgi_ts *corgi_ts = platform_get_drvdata(dev);
corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
/* Enable Falling Edge */
@@ -264,10 +264,9 @@ static int corgits_resume(struct device *dev)
#define corgits_resume NULL
#endif
-static int __init corgits_probe(struct device *dev)
+static int __init corgits_probe(struct platform_device *pdev)
{
struct corgi_ts *corgi_ts;
- struct platform_device *pdev = to_platform_device(dev);
struct input_dev *input_dev;
int err = -ENOMEM;
@@ -276,9 +275,9 @@ static int __init corgits_probe(struct device *dev)
if (!corgi_ts || !input_dev)
goto fail;
- dev_set_drvdata(dev, corgi_ts);
+ platform_set_drvdata(pdev, corgi_ts);
- corgi_ts->machinfo = dev->platform_data;
+ corgi_ts->machinfo = pdev->dev.platform_data;
corgi_ts->irq_gpio = platform_get_irq(pdev, 0);
if (corgi_ts->irq_gpio < 0) {
@@ -298,7 +297,7 @@ static int __init corgits_probe(struct device *dev)
input_dev->id.vendor = 0x0001;
input_dev->id.product = 0x0002;
input_dev->id.version = 0x0100;
- input_dev->cdev.dev = dev;
+ input_dev->cdev.dev = &pdev->dev;
input_dev->private = corgi_ts;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
@@ -339,9 +338,9 @@ static int __init corgits_probe(struct device *dev)
}
-static int corgits_remove(struct device *dev)
+static int corgits_remove(struct platform_device *pdev)
{
- struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
+ struct corgi_ts *corgi_ts = platform_get_drvdata(pdev);
free_irq(corgi_ts->irq_gpio, NULL);
del_timer_sync(&corgi_ts->timer);
@@ -351,23 +350,24 @@ static int corgits_remove(struct device *dev)
return 0;
}
-static struct device_driver corgits_driver = {
- .name = "corgi-ts",
- .bus = &platform_bus_type,
+static struct platform_driver corgits_driver = {
.probe = corgits_probe,
.remove = corgits_remove,
.suspend = corgits_suspend,
.resume = corgits_resume,
+ .driver = {
+ .name = "corgi-ts",
+ },
};
static int __devinit corgits_init(void)
{
- return driver_register(&corgits_driver);
+ return platform_driver_register(&corgits_driver);
}
static void __exit corgits_exit(void)
{
- driver_unregister(&corgits_driver);
+ platform_driver_unregister(&corgits_driver);
}
module_init(corgits_init);
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index 801c98f..c821059 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -110,7 +110,7 @@ config HISAX_16_3
config HISAX_TELESPCI
bool "Teles PCI"
- depends on PCI && (BROKEN || !(SPARC64 || PPC))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help
This enables HiSax support for the Teles PCI.
See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -238,7 +238,7 @@ config HISAX_MIC
config HISAX_NETJET
bool "NETjet card"
- depends on PCI && (BROKEN || !(SPARC64 || PPC))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help
This enables HiSax support for the NetJet from Traverse
Technologies.
@@ -249,7 +249,7 @@ config HISAX_NETJET
config HISAX_NETJET_U
bool "NETspider U card"
- depends on PCI && (BROKEN || !(SPARC64 || PPC))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help
This enables HiSax support for the Netspider U interface ISDN card
from Traverse Technologies.
@@ -317,7 +317,7 @@ config HISAX_GAZEL
config HISAX_HFC_PCI
bool "HFC PCI-Bus cards"
- depends on PCI && (BROKEN || !(SPARC64 || PPC))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help
This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
@@ -344,14 +344,14 @@ config HISAX_HFC_SX
config HISAX_ENTERNOW_PCI
bool "Formula-n enter:now PCI card"
- depends on PCI && (BROKEN || !(SPARC64 || PPC))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help
This enables HiSax support for the Formula-n enter:now PCI
ISDN card.
config HISAX_AMD7930
bool "Am7930 (EXPERIMENTAL)"
- depends on EXPERIMENTAL && (SPARC32 || SPARC64)
+ depends on EXPERIMENTAL && SPARC
help
This enables HiSax support for the AMD7930 chips on some SPARCs.
This code is not finished yet.
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index 32bf0d5..f8457ef 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -71,78 +71,68 @@ typedef struct {
/****************************************/
static struct usb_device_id hfcusb_idtab[] = {
{
- .idVendor = 0x0959,
- .idProduct = 0x2bd0,
+ USB_DEVICE(0x0959, 0x2bd0),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_OFF, {4, 0, 2, 1},
"ISDN USB TA (Cologne Chip HFC-S USB based)"}),
},
{
- .idVendor = 0x0675,
- .idProduct = 0x1688,
+ USB_DEVICE(0x0675, 0x1688),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {1, 2, 0, 0},
"DrayTek miniVigor 128 USB ISDN TA"}),
},
{
- .idVendor = 0x07b0,
- .idProduct = 0x0007,
+ USB_DEVICE(0x07b0, 0x0007),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16},
"Billion tiny USB ISDN TA 128"}),
},
{
- .idVendor = 0x0742,
- .idProduct = 0x2008,
+ USB_DEVICE(0x0742, 0x2008),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1},
"Stollmann USB TA"}),
},
{
- .idVendor = 0x0742,
- .idProduct = 0x2009,
+ USB_DEVICE(0x0742, 0x2009),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1},
"Aceex USB ISDN TA"}),
},
{
- .idVendor = 0x0742,
- .idProduct = 0x200A,
+ USB_DEVICE(0x0742, 0x200A),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1},
"OEM USB ISDN TA"}),
},
{
- .idVendor = 0x08e3,
- .idProduct = 0x0301,
+ USB_DEVICE(0x08e3, 0x0301),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {2, 0, 1, 4},
"Olitec USB RNIS"}),
},
{
- .idVendor = 0x07fa,
- .idProduct = 0x0846,
+ USB_DEVICE(0x07fa, 0x0846),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16},
"Bewan Modem RNIS USB"}),
},
{
- .idVendor = 0x07fa,
- .idProduct = 0x0847,
+ USB_DEVICE(0x07fa, 0x0847),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16},
"Djinn Numeris USB"}),
},
{
- .idVendor = 0x07b0,
- .idProduct = 0x0006,
+ USB_DEVICE(0x07b0, 0x0006),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16},
"Twister ISDN TA"}),
},
+ { }
};
-
/***************************************************************/
/* structure defining input+output fifos (interrupt/bulk mode) */
/***************************************************************/
diff --git a/drivers/isdn/pcbit/Kconfig b/drivers/isdn/pcbit/Kconfig
index f06997f..0933881 100644
--- a/drivers/isdn/pcbit/Kconfig
+++ b/drivers/isdn/pcbit/Kconfig
@@ -3,7 +3,7 @@
#
config ISDN_DRV_PCBIT
tristate "PCBIT-D support"
- depends on ISDN_I4L && ISA && (BROKEN || !PPC)
+ depends on ISDN_I4L && ISA && (BROKEN || X86)
help
This enables support for the PCBIT ISDN-card. This card is
manufactured in Portugal by Octal. For running this card,
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 5131530..252d55d 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -326,9 +326,9 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait)
}
}
- ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE);
+ ret = page->mapping->a_ops->prepare_write(bitmap->file, page, 0, PAGE_SIZE);
if (!ret)
- ret = page->mapping->a_ops->commit_write(NULL, page, 0,
+ ret = page->mapping->a_ops->commit_write(bitmap->file, page, 0,
PAGE_SIZE);
if (ret) {
unlock_page(page);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index adf960d..78c7418 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3156,7 +3156,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
if (cnt > 0 ) {
printk(KERN_WARNING
"md: %s(pid %d) used deprecated START_ARRAY ioctl. "
- "This will not be supported beyond 2.6\n",
+ "This will not be supported beyond July 2006\n",
current->comm, current->pid);
cnt--;
}
@@ -3437,10 +3437,19 @@ static int md_thread(void * arg)
allow_signal(SIGKILL);
while (!kthread_should_stop()) {
- wait_event_timeout(thread->wqueue,
- test_bit(THREAD_WAKEUP, &thread->flags)
- || kthread_should_stop(),
- thread->timeout);
+ /* We need to wait INTERRUPTIBLE so that
+ * we don't add to the load-average.
+ * That means we need to be sure no signals are
+ * pending
+ */
+ if (signal_pending(current))
+ flush_signals(current);
+
+ wait_event_interruptible_timeout
+ (thread->wqueue,
+ test_bit(THREAD_WAKEUP, &thread->flags)
+ || kthread_should_stop(),
+ thread->timeout);
try_to_freeze();
clear_bit(THREAD_WAKEUP, &thread->flags);
@@ -3837,11 +3846,20 @@ static int is_mddev_idle(mddev_t *mddev)
curr_events = disk_stat_read(disk, sectors[0]) +
disk_stat_read(disk, sectors[1]) -
atomic_read(&disk->sync_io);
- /* Allow some slack between valud of curr_events and last_events,
- * as there are some uninteresting races.
+ /* The difference between curr_events and last_events
+ * will be affected by any new non-sync IO (making
+ * curr_events bigger) and any difference in the amount of
+ * in-flight syncio (making current_events bigger or smaller)
+ * The amount in-flight is currently limited to
+ * 32*64K in raid1/10 and 256*PAGE_SIZE in raid5/6
+ * which is at most 4096 sectors.
+ * These numbers are fairly fragile and should be made
+ * more robust, probably by enforcing the
+ * 'window size' that md_do_sync sort-of uses.
+ *
* Note: the following is an unsigned comparison.
*/
- if ((curr_events - rdev->last_events + 32) > 64) {
+ if ((curr_events - rdev->last_events + 4096) > 8192) {
rdev->last_events = curr_events;
idle = 0;
}
@@ -4100,7 +4118,7 @@ static void md_do_sync(mddev_t *mddev)
if (currspeed > sysctl_speed_limit_min) {
if ((currspeed > sysctl_speed_limit_max) ||
!is_mddev_idle(mddev)) {
- msleep(250);
+ msleep(500);
goto repeat;
}
}
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 4b71fd6..7972c73 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -126,6 +126,66 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_winfast);
+IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
+ [ 0x59 ] = KEY_MUTE,
+ [ 0x4a ] = KEY_POWER,
+
+ [ 0x18 ] = KEY_TEXT,
+ [ 0x26 ] = KEY_TV,
+ [ 0x3d ] = KEY_PRINT,
+
+ [ 0x48 ] = KEY_RED,
+ [ 0x04 ] = KEY_GREEN,
+ [ 0x11 ] = KEY_YELLOW,
+ [ 0x00 ] = KEY_BLUE,
+
+ [ 0x2d ] = KEY_VOLUMEUP,
+ [ 0x1e ] = KEY_VOLUMEDOWN,
+
+ [ 0x49 ] = KEY_MENU,
+
+ [ 0x16 ] = KEY_CHANNELUP,
+ [ 0x17 ] = KEY_CHANNELDOWN,
+
+ [ 0x20 ] = KEY_UP,
+ [ 0x21 ] = KEY_DOWN,
+ [ 0x22 ] = KEY_LEFT,
+ [ 0x23 ] = KEY_RIGHT,
+ [ 0x0d ] = KEY_SELECT,
+
+
+
+ [ 0x08 ] = KEY_BACK,
+ [ 0x07 ] = KEY_REFRESH,
+
+ [ 0x2f ] = KEY_ZOOM,
+ [ 0x29 ] = KEY_RECORD,
+
+ [ 0x4b ] = KEY_PAUSE,
+ [ 0x4d ] = KEY_REWIND,
+ [ 0x2e ] = KEY_PLAY,
+ [ 0x4e ] = KEY_FORWARD,
+ [ 0x53 ] = KEY_PREVIOUS,
+ [ 0x4c ] = KEY_STOP,
+ [ 0x54 ] = KEY_NEXT,
+
+ [ 0x69 ] = KEY_KP0,
+ [ 0x6a ] = KEY_KP1,
+ [ 0x6b ] = KEY_KP2,
+ [ 0x6c ] = KEY_KP3,
+ [ 0x6d ] = KEY_KP4,
+ [ 0x6e ] = KEY_KP5,
+ [ 0x6f ] = KEY_KP6,
+ [ 0x70 ] = KEY_KP7,
+ [ 0x71 ] = KEY_KP8,
+ [ 0x72 ] = KEY_KP9,
+
+ [ 0x74 ] = KEY_CHANNEL,
+ [ 0x0a ] = KEY_BACKSPACE,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_pinnacle);
+
/* empty keytable, can be used as placeholder for not-yet created keytables */
IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
[ 42 ] = KEY_COFFEE,
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index d7417ea..2583a86 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -7,6 +7,7 @@ config DVB_B2C2_FLEXCOP
select DVB_NXT2002
select DVB_STV0297
select DVB_BCM3510
+ select DVB_LGDT330X
help
Support for the digital TV receiver chip made by B2C2 Inc. included in
Technisats PCI cards and USB boxes.
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index a1607e7..fb394a0d 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -276,7 +276,7 @@ static void cinergyt2_free_stream_urbs (struct cinergyt2 *cinergyt2)
if (cinergyt2->stream_urb[i])
usb_free_urb(cinergyt2->stream_urb[i]);
- pci_free_consistent(NULL, STREAM_URB_COUNT*STREAM_BUF_SIZE,
+ usb_buffer_free(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE,
cinergyt2->streambuf, cinergyt2->streambuf_dmahandle);
}
@@ -284,9 +284,8 @@ static int cinergyt2_alloc_stream_urbs (struct cinergyt2 *cinergyt2)
{
int i;
- cinergyt2->streambuf = pci_alloc_consistent(NULL,
- STREAM_URB_COUNT*STREAM_BUF_SIZE,
- &cinergyt2->streambuf_dmahandle);
+ cinergyt2->streambuf = usb_buffer_alloc(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE,
+ SLAB_KERNEL, &cinergyt2->streambuf_dmahandle);
if (!cinergyt2->streambuf) {
dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n");
return -ENOMEM;
@@ -780,6 +779,8 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
input_register_device(cinergyt2->rc_input_dev);
schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
+
+ return 0;
}
static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2)
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 199b011..1a3b3c7 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -333,4 +333,18 @@ config VIDEO_M32R_AR_M64278
Say Y here to use the Renesas M64278E-800 camera module,
which supports VGA(640x480 pixcels) size of images.
+config VIDEO_AUDIO_DECODER
+ tristate "Add support for additional audio chipsets"
+ depends on VIDEO_DEV && I2C && EXPERIMENTAL
+ ---help---
+ Say Y here to compile drivers for WM8775 and CS53L32A audio
+ decoders.
+
+config VIDEO_DECODER
+ tristate "Add support for additional video chipsets"
+ depends on VIDEO_DEV && I2C && EXPERIMENTAL
+ ---help---
+ Say Y here to compile drivers for SAA7115, SAA7127 and CX25840
+ video decoders.
+
endmenu
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 3ac4659..82060f9 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -36,10 +36,11 @@ obj-$(CONFIG_VIDEO_CPIA) += cpia.o
obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
obj-$(CONFIG_VIDEO_MEYE) += meye.o
-obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
+obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/
obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o
+obj-$(CONFIG_VIDEO_AUDIO_DECODER) += wm8775.o cs53l32a.o
obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
@@ -55,4 +56,6 @@ obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
+obj-$(CONFIG_VIDEO_DECODER) += saa7115.o cx25840/ saa7127.o
+
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 3413bac..e31ebb1 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -2133,7 +2133,10 @@ struct tvcard bttv_tvcards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.has_dvb = 1,
+ .has_remote = 1,
+ .gpiomask = 0x1b,
.no_gpioirq = 1,
+ .any_irq = 1,
},
[BTTV_BOARD_PV143] = {
/* Jorge Boncompte - DTI2 <jorge@dti2.net> */
@@ -2796,7 +2799,24 @@ struct tvcard bttv_tvcards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
},
-
+ /* ---- card 0x8e ---------------------------------- */
+ [BTTV_BOARD_SABRENT_TVFM] = {
+ .name = "Sabrent TV-FM (bttv version)",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x108007,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 100000, 100002, 100002, 100000},
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_TNF_5335MF,
+ .tuner_addr = ADDR_UNSET,
+ .has_radio = 1,
+ },
};
static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3367,6 +3387,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
btv->has_remote=1;
if (!bttv_tvcards[btv->c.type].no_gpioirq)
btv->gpioirq=1;
+ if (bttv_tvcards[btv->c.type].any_irq)
+ btv->any_irq = 1;
if (bttv_tvcards[btv->c.type].audio_hook)
btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 0005741..709099f 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -3667,6 +3667,10 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
int handled = 0;
btv=(struct bttv *)dev_id;
+
+ if (btv->any_irq)
+ handled = bttv_any_irq(&btv->c);
+
count=0;
while (1) {
/* get/clear interrupt status bits */
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index 575ce8b..616a5b7 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -113,6 +113,24 @@ void bttv_gpio_irq(struct bttv_core *core)
}
}
+int bttv_any_irq(struct bttv_core *core)
+{
+ struct bttv_sub_driver *drv;
+ struct bttv_sub_device *dev;
+ struct list_head *item;
+ int handled = 0;
+
+ list_for_each(item,&core->subs) {
+ dev = list_entry(item,struct bttv_sub_device,list);
+ drv = to_bttv_sub_drv(dev->dev.driver);
+ if (drv && drv->any_irq) {
+ if (drv->any_irq(dev))
+ handled = 1;
+ }
+ }
+ return handled;
+}
+
/* ----------------------------------------------------------------------- */
/* external: sub-driver register/unregister */
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index 124ea41..93298f0 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -162,6 +162,7 @@
#define BTTV_BOARD_PV_M4900 0x8b
#define BTTV_BOARD_OSPREY440 0x8c
#define BTTV_BOARD_ASOUND_SKYEYE 0x8d
+#define BTTV_BOARD_SABRENT_TVFM 0x8e
/* i2c address list */
#define I2C_TSA5522 0xc2
@@ -234,6 +235,7 @@ struct tvcard
unsigned int has_dvb:1;
unsigned int has_remote:1;
unsigned int no_gpioirq:1;
+ unsigned int any_irq:1;
/* other settings */
unsigned int pll;
@@ -333,6 +335,7 @@ struct bttv_sub_driver {
struct device_driver drv;
char wanted[BUS_ID_SIZE];
void (*gpio_irq)(struct bttv_sub_device *sub);
+ int (*any_irq)(struct bttv_sub_device *sub);
};
#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv)
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 386f546..3aa9c6e 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -208,6 +208,7 @@ extern struct bus_type bttv_sub_bus_type;
int bttv_sub_add_device(struct bttv_core *core, char *name);
int bttv_sub_del_devices(struct bttv_core *core);
void bttv_gpio_irq(struct bttv_core *core);
+int bttv_any_irq(struct bttv_core *core);
/* ---------------------------------------------------------- */
@@ -273,6 +274,7 @@ struct bttv {
struct bttv_pll_info pll;
int triton1;
int gpioirq;
+ int any_irq;
int use_i2c_hw;
/* old gpio interface */
diff --git a/drivers/media/video/cx25840/Makefile b/drivers/media/video/cx25840/Makefile
new file mode 100644
index 0000000..543ebac
--- /dev/null
+++ b/drivers/media/video/cx25840/Makefile
@@ -0,0 +1,6 @@
+cx25840-objs := cx25840-core.o cx25840-audio.o cx25840-firmware.o \
+ cx25840-vbi.o
+
+obj-$(CONFIG_VIDEO_DECODER) += cx25840.o
+
+EXTRA_CFLAGS += -I$(src)/..
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
new file mode 100644
index 0000000..740908f
--- /dev/null
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -0,0 +1,368 @@
+/* cx25840 audio functions
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <media/audiochip.h>
+#include <media/v4l2-common.h>
+
+#include "cx25840.h"
+
+inline static int set_audclk_freq(struct i2c_client *client,
+ enum v4l2_audio_clock_freq freq)
+{
+ struct cx25840_state *state = i2c_get_clientdata(client);
+
+ /* assert soft reset */
+ cx25840_and_or(client, 0x810, ~0x1, 0x01);
+
+ /* common for all inputs and rates */
+ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
+ cx25840_write(client, 0x127, 0x50);
+
+ switch (state->audio_input) {
+ case AUDIO_TUNER:
+ switch (freq) {
+ case V4L2_AUDCLK_32_KHZ:
+ /* VID_PLL and AUX_PLL */
+ cx25840_write4(client, 0x108, 0x0f040610);
+
+ /* AUX_PLL_FRAC */
+ cx25840_write4(client, 0x110, 0xee39bb01);
+
+ /* src3/4/6_ctl = 0x0801f77f */
+ cx25840_write4(client, 0x900, 0x7ff70108);
+ cx25840_write4(client, 0x904, 0x7ff70108);
+ cx25840_write4(client, 0x90c, 0x7ff70108);
+ break;
+
+ case V4L2_AUDCLK_441_KHZ:
+ /* VID_PLL and AUX_PLL */
+ cx25840_write4(client, 0x108, 0x0f040910);
+
+ /* AUX_PLL_FRAC */
+ cx25840_write4(client, 0x110, 0xd66bec00);
+
+ /* src3/4/6_ctl = 0x08016d59 */
+ cx25840_write4(client, 0x900, 0x596d0108);
+ cx25840_write4(client, 0x904, 0x596d0108);
+ cx25840_write4(client, 0x90c, 0x596d0108);
+ break;
+
+ case V4L2_AUDCLK_48_KHZ:
+ /* VID_PLL and AUX_PLL */
+ cx25840_write4(client, 0x108, 0x0f040a10);
+
+ /* AUX_PLL_FRAC */
+ cx25840_write4(client, 0x110, 0xe5d69800);
+
+ /* src3/4/6_ctl = 0x08014faa */
+ cx25840_write4(client, 0x900, 0xaa4f0108);
+ cx25840_write4(client, 0x904, 0xaa4f0108);
+ cx25840_write4(client, 0x90c, 0xaa4f0108);
+ break;
+ }
+ break;
+
+ case AUDIO_EXTERN_1:
+ case AUDIO_EXTERN_2:
+ case AUDIO_INTERN:
+ case AUDIO_RADIO:
+ switch (freq) {
+ case V4L2_AUDCLK_32_KHZ:
+ /* VID_PLL and AUX_PLL */
+ cx25840_write4(client, 0x108, 0x0f04081e);
+
+ /* AUX_PLL_FRAC */
+ cx25840_write4(client, 0x110, 0x69082a01);
+
+ /* src1_ctl = 0x08010000 */
+ cx25840_write4(client, 0x8f8, 0x00000108);
+
+ /* src3/4/6_ctl = 0x08020000 */
+ cx25840_write4(client, 0x900, 0x00000208);
+ cx25840_write4(client, 0x904, 0x00000208);
+ cx25840_write4(client, 0x90c, 0x00000208);
+
+ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
+ cx25840_write(client, 0x127, 0x54);
+ break;
+
+ case V4L2_AUDCLK_441_KHZ:
+ /* VID_PLL and AUX_PLL */
+ cx25840_write4(client, 0x108, 0x0f040918);
+
+ /* AUX_PLL_FRAC */
+ cx25840_write4(client, 0x110, 0xd66bec00);
+
+ /* src1_ctl = 0x08010000 */
+ cx25840_write4(client, 0x8f8, 0xcd600108);
+
+ /* src3/4/6_ctl = 0x08020000 */
+ cx25840_write4(client, 0x900, 0x85730108);
+ cx25840_write4(client, 0x904, 0x85730108);
+ cx25840_write4(client, 0x90c, 0x85730108);
+ break;
+
+ case V4L2_AUDCLK_48_KHZ:
+ /* VID_PLL and AUX_PLL */
+ cx25840_write4(client, 0x108, 0x0f040a18);
+
+ /* AUX_PLL_FRAC */
+ cx25840_write4(client, 0x110, 0xe5d69800);
+
+ /* src1_ctl = 0x08010000 */
+ cx25840_write4(client, 0x8f8, 0x00800108);
+
+ /* src3/4/6_ctl = 0x08020000 */
+ cx25840_write4(client, 0x900, 0x55550108);
+ cx25840_write4(client, 0x904, 0x55550108);
+ cx25840_write4(client, 0x90c, 0x55550108);
+ break;
+ }
+ break;
+ }
+
+ /* deassert soft reset */
+ cx25840_and_or(client, 0x810, ~0x1, 0x00);
+
+ state->audclk_freq = freq;
+
+ return 0;
+}
+
+static int set_input(struct i2c_client *client, int audio_input)
+{
+ struct cx25840_state *state = i2c_get_clientdata(client);
+
+ cx25840_dbg("set audio input (%d)\n", audio_input);
+
+ /* stop microcontroller */
+ cx25840_and_or(client, 0x803, ~0x10, 0);
+
+ /* Mute everything to prevent the PFFT! */
+ cx25840_write(client, 0x8d3, 0x1f);
+
+ switch (audio_input) {
+ case AUDIO_TUNER:
+ /* Set Path1 to Analog Demod Main Channel */
+ cx25840_write4(client, 0x8d0, 0x7038061f);
+
+ /* When the microcontroller detects the
+ * audio format, it will unmute the lines */
+ cx25840_and_or(client, 0x803, ~0x10, 0x10);
+ break;
+
+ case AUDIO_EXTERN_1:
+ case AUDIO_EXTERN_2:
+ case AUDIO_INTERN:
+ case AUDIO_RADIO:
+ /* Set Path1 to Serial Audio Input */
+ cx25840_write4(client, 0x8d0, 0x12100101);
+
+ /* The microcontroller should not be started for the
+ * non-tuner inputs: autodetection is specific for
+ * TV audio. */
+ break;
+
+ default:
+ cx25840_dbg("Invalid audio input selection %d\n", audio_input);
+ return -EINVAL;
+ }
+
+ state->audio_input = audio_input;
+
+ return set_audclk_freq(client, state->audclk_freq);
+}
+
+inline static int get_volume(struct i2c_client *client)
+{
+ /* Volume runs +18dB to -96dB in 1/2dB steps
+ * change to fit the msp3400 -114dB to +12dB range */
+
+ /* check PATH1_VOLUME */
+ int vol = 228 - cx25840_read(client, 0x8d4);
+ vol = (vol / 2) + 23;
+ return vol << 9;
+}
+
+inline static void set_volume(struct i2c_client *client, int volume)
+{
+ /* First convert the volume to msp3400 values (0-127) */
+ int vol = volume >> 9;
+ /* now scale it up to cx25840 values
+ * -114dB to -96dB maps to 0
+ * this should be 19, but in my testing that was 4dB too loud */
+ if (vol <= 23) {
+ vol = 0;
+ } else {
+ vol -= 23;
+ }
+
+ /* PATH1_VOLUME */
+ cx25840_write(client, 0x8d4, 228 - (vol * 2));
+}
+
+inline static int get_bass(struct i2c_client *client)
+{
+ /* bass is 49 steps +12dB to -12dB */
+
+ /* check PATH1_EQ_BASS_VOL */
+ int bass = cx25840_read(client, 0x8d9) & 0x3f;
+ bass = (((48 - bass) * 0xffff) + 47) / 48;
+ return bass;
+}
+
+inline static void set_bass(struct i2c_client *client, int bass)
+{
+ /* PATH1_EQ_BASS_VOL */
+ cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
+}
+
+inline static int get_treble(struct i2c_client *client)
+{
+ /* treble is 49 steps +12dB to -12dB */
+
+ /* check PATH1_EQ_TREBLE_VOL */
+ int treble = cx25840_read(client, 0x8db) & 0x3f;
+ treble = (((48 - treble) * 0xffff) + 47) / 48;
+ return treble;
+}
+
+inline static void set_treble(struct i2c_client *client, int treble)
+{
+ /* PATH1_EQ_TREBLE_VOL */
+ cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
+}
+
+inline static int get_balance(struct i2c_client *client)
+{
+ /* balance is 7 bit, 0 to -96dB */
+
+ /* check PATH1_BAL_LEVEL */
+ int balance = cx25840_read(client, 0x8d5) & 0x7f;
+ /* check PATH1_BAL_LEFT */
+ if ((cx25840_read(client, 0x8d5) & 0x80) == 0)
+ balance = 0x80 - balance;
+ else
+ balance = 0x80 + balance;
+ return balance << 8;
+}
+
+inline static void set_balance(struct i2c_client *client, int balance)
+{
+ int bal = balance >> 8;
+ if (bal > 0x80) {
+ /* PATH1_BAL_LEFT */
+ cx25840_and_or(client, 0x8d5, 0x7f, 0x80);
+ /* PATH1_BAL_LEVEL */
+ cx25840_and_or(client, 0x8d5, ~0x7f, bal & 0x7f);
+ } else {
+ /* PATH1_BAL_LEFT */
+ cx25840_and_or(client, 0x8d5, 0x7f, 0x00);
+ /* PATH1_BAL_LEVEL */
+ cx25840_and_or(client, 0x8d5, ~0x7f, 0x80 - bal);
+ }
+}
+
+inline static int get_mute(struct i2c_client *client)
+{
+ /* check SRC1_MUTE_EN */
+ return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0;
+}
+
+inline static void set_mute(struct i2c_client *client, int mute)
+{
+ struct cx25840_state *state = i2c_get_clientdata(client);
+
+ if (state->audio_input == AUDIO_TUNER) {
+ /* Must turn off microcontroller in order to mute sound.
+ * Not sure if this is the best method, but it does work.
+ * If the microcontroller is running, then it will undo any
+ * changes to the mute register. */
+ if (mute) {
+ /* disable microcontroller */
+ cx25840_and_or(client, 0x803, ~0x10, 0x00);
+ cx25840_write(client, 0x8d3, 0x1f);
+ } else {
+ /* enable microcontroller */
+ cx25840_and_or(client, 0x803, ~0x10, 0x10);
+ }
+ } else {
+ /* SRC1_MUTE_EN */
+ cx25840_and_or(client, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
+ }
+}
+
+int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+ struct v4l2_control *ctrl = arg;
+
+ switch (cmd) {
+ case AUDC_SET_INPUT:
+ return set_input(client, *(int *)arg);
+ case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+ return set_audclk_freq(client, *(enum v4l2_audio_clock_freq *)arg);
+ case VIDIOC_G_CTRL:
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = get_volume(client);
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ ctrl->value = get_bass(client);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ ctrl->value = get_treble(client);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ ctrl->value = get_balance(client);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = get_mute(client);
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case VIDIOC_S_CTRL:
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ set_volume(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ set_bass(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ set_treble(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ set_balance(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ set_mute(client, ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
new file mode 100644
index 0000000..f6afeec
--- /dev/null
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -0,0 +1,1020 @@
+/* cx25840 - Conexant CX25840 audio/video decoder driver
+ *
+ * Copyright (C) 2004 Ulf Eklund
+ *
+ * Based on the saa7115 driver and on the first verison of Chris Kennedy's
+ * cx25840 driver.
+ *
+ * Changes by Tyler Trafford <tatrafford@comcast.net>
+ * - cleanup/rewrite for V4L2 API (2005)
+ *
+ * VBI support by Hans Verkuil <hverkuil@xs4all.nl>.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <media/audiochip.h>
+#include <media/v4l2-common.h>
+
+#include "cx25840.h"
+
+MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver");
+MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford");
+MODULE_LICENSE("GPL");
+
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+
+
+int cx25840_debug = 0;
+
+module_param(cx25840_debug, bool, 0644);
+
+MODULE_PARM_DESC(cx25840_debug, "Debugging messages [0=Off (default) 1=On]");
+
+I2C_CLIENT_INSMOD;
+
+/* ----------------------------------------------------------------------- */
+
+int cx25840_write(struct i2c_client *client, u16 addr, u8 value)
+{
+ u8 buffer[3];
+ buffer[0] = addr >> 8;
+ buffer[1] = addr & 0xff;
+ buffer[2] = value;
+ return i2c_master_send(client, buffer, 3);
+}
+
+int cx25840_write4(struct i2c_client *client, u16 addr, u32 value)
+{
+ u8 buffer[6];
+ buffer[0] = addr >> 8;
+ buffer[1] = addr & 0xff;
+ buffer[2] = value >> 24;
+ buffer[3] = (value >> 16) & 0xff;
+ buffer[4] = (value >> 8) & 0xff;
+ buffer[5] = value & 0xff;
+ return i2c_master_send(client, buffer, 6);
+}
+
+u8 cx25840_read(struct i2c_client * client, u16 addr)
+{
+ u8 buffer[2];
+ buffer[0] = addr >> 8;
+ buffer[1] = addr & 0xff;
+
+ if (i2c_master_send(client, buffer, 2) < 2)
+ return 0;
+
+ if (i2c_master_recv(client, buffer, 1) < 1)
+ return 0;
+
+ return buffer[0];
+}
+
+u32 cx25840_read4(struct i2c_client * client, u16 addr)
+{
+ u8 buffer[4];
+ buffer[0] = addr >> 8;
+ buffer[1] = addr & 0xff;
+
+ if (i2c_master_send(client, buffer, 2) < 2)
+ return 0;
+
+ if (i2c_master_recv(client, buffer, 4) < 4)
+ return 0;
+
+ return (buffer[0] << 24) | (buffer[1] << 16) |
+ (buffer[2] << 8) | buffer[3];
+}
+
+int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask,
+ u8 or_value)
+{
+ return cx25840_write(client, addr,
+ (cx25840_read(client, addr) & and_mask) |
+ or_value);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int set_input(struct i2c_client *, enum cx25840_input);
+static void input_change(struct i2c_client *);
+static void log_status(struct i2c_client *client);
+
+/* ----------------------------------------------------------------------- */
+
+static inline void init_dll1(struct i2c_client *client)
+{
+ /* This is the Hauppauge sequence used to
+ * initialize the Delay Lock Loop 1 (ADC DLL). */
+ cx25840_write(client, 0x159, 0x23);
+ cx25840_write(client, 0x15a, 0x87);
+ cx25840_write(client, 0x15b, 0x06);
+ cx25840_write(client, 0x159, 0xe1);
+ cx25840_write(client, 0x15a, 0x86);
+ cx25840_write(client, 0x159, 0xe0);
+ cx25840_write(client, 0x159, 0xe1);
+ cx25840_write(client, 0x15b, 0x10);
+}
+
+static inline void init_dll2(struct i2c_client *client)
+{
+ /* This is the Hauppauge sequence used to
+ * initialize the Delay Lock Loop 2 (ADC DLL). */
+ cx25840_write(client, 0x15d, 0xe3);
+ cx25840_write(client, 0x15e, 0x86);
+ cx25840_write(client, 0x15f, 0x06);
+ cx25840_write(client, 0x15d, 0xe1);
+ cx25840_write(client, 0x15d, 0xe0);
+ cx25840_write(client, 0x15d, 0xe1);
+}
+
+static void cx25840_initialize(struct i2c_client *client, int loadfw)
+{
+ struct cx25840_state *state = i2c_get_clientdata(client);
+
+ /* datasheet startup in numbered steps, refer to page 3-77 */
+ /* 2. */
+ cx25840_and_or(client, 0x803, ~0x10, 0x00);
+ /* The default of this register should be 4, but I get 0 instead.
+ * Set this register to 4 manually. */
+ cx25840_write(client, 0x000, 0x04);
+ /* 3. */
+ init_dll1(client);
+ init_dll2(client);
+ cx25840_write(client, 0x136, 0x0a);
+ /* 4. */
+ cx25840_write(client, 0x13c, 0x01);
+ cx25840_write(client, 0x13c, 0x00);
+ /* 5. */
+ if (loadfw)
+ cx25840_loadfw(client);
+ /* 6. */
+ cx25840_write(client, 0x115, 0x8c);
+ cx25840_write(client, 0x116, 0x07);
+ cx25840_write(client, 0x118, 0x02);
+ /* 7. */
+ cx25840_write(client, 0x4a5, 0x80);
+ cx25840_write(client, 0x4a5, 0x00);
+ cx25840_write(client, 0x402, 0x00);
+ /* 8. */
+ cx25840_write(client, 0x401, 0x18);
+ cx25840_write(client, 0x4a2, 0x10);
+ cx25840_write(client, 0x402, 0x04);
+ /* 10. */
+ cx25840_write(client, 0x8d3, 0x1f);
+ cx25840_write(client, 0x8e3, 0x03);
+
+ cx25840_vbi_setup(client);
+
+ /* trial and error says these are needed to get audio */
+ cx25840_write(client, 0x914, 0xa0);
+ cx25840_write(client, 0x918, 0xa0);
+ cx25840_write(client, 0x919, 0x01);
+
+ /* stereo prefered */
+ cx25840_write(client, 0x809, 0x04);
+ /* AC97 shift */
+ cx25840_write(client, 0x8cf, 0x0f);
+
+ /* (re)set video input */
+ set_input(client, state->input);
+ /* (re)set audio input */
+ cx25840_audio(client, AUDC_SET_INPUT, &state->audio_input);
+
+ /* start microcontroller */
+ cx25840_and_or(client, 0x803, ~0x10, 0x10);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void input_change(struct i2c_client *client)
+{
+ v4l2_std_id std = cx25840_get_v4lstd(client);
+
+ if (std & V4L2_STD_PAL) {
+ /* Follow tuner change procedure for PAL */
+ cx25840_write(client, 0x808, 0xff);
+ cx25840_write(client, 0x80b, 0x10);
+ } else if (std & V4L2_STD_SECAM) {
+ /* Select autodetect for SECAM */
+ cx25840_write(client, 0x808, 0xff);
+ cx25840_write(client, 0x80b, 0x10);
+ } else if (std & V4L2_STD_NTSC) {
+ /* NTSC */
+ cx25840_write(client, 0x808, 0xf6);
+ cx25840_write(client, 0x80b, 0x00);
+ }
+
+ if (cx25840_read(client, 0x803) & 0x10) {
+ /* restart audio decoder microcontroller */
+ cx25840_and_or(client, 0x803, ~0x10, 0x00);
+ cx25840_and_or(client, 0x803, ~0x10, 0x10);
+ }
+}
+
+static int set_input(struct i2c_client *client, enum cx25840_input input)
+{
+ struct cx25840_state *state = i2c_get_clientdata(client);
+
+ cx25840_dbg("decoder set input (%d)\n", input);
+
+ switch (input) {
+ case CX25840_TUNER:
+ cx25840_dbg("now setting Tuner input\n");
+
+ if (state->cardtype == CARDTYPE_PVR150) {
+ /* CH_SEL_ADC2=1 */
+ cx25840_and_or(client, 0x102, ~0x2, 0x02);
+ }
+
+ /* Video Input Control */
+ if (state->cardtype == CARDTYPE_PG600) {
+ cx25840_write(client, 0x103, 0x11);
+ } else {
+ cx25840_write(client, 0x103, 0x46);
+ }
+
+ /* INPUT_MODE=0 */
+ cx25840_and_or(client, 0x401, ~0x6, 0x00);
+ break;
+
+ case CX25840_COMPOSITE0:
+ case CX25840_COMPOSITE1:
+ cx25840_dbg("now setting Composite input\n");
+
+ /* Video Input Control */
+ if (state->cardtype == CARDTYPE_PG600) {
+ cx25840_write(client, 0x103, 0x00);
+ } else {
+ cx25840_write(client, 0x103, 0x02);
+ }
+
+ /* INPUT_MODE=0 */
+ cx25840_and_or(client, 0x401, ~0x6, 0x00);
+ break;
+
+ case CX25840_SVIDEO0:
+ case CX25840_SVIDEO1:
+ cx25840_dbg("now setting S-Video input\n");
+
+ /* CH_SEL_ADC2=0 */
+ cx25840_and_or(client, 0x102, ~0x2, 0x00);
+
+ /* Video Input Control */
+ if (state->cardtype == CARDTYPE_PG600) {
+ cx25840_write(client, 0x103, 0x02);
+ } else {
+ cx25840_write(client, 0x103, 0x10);
+ }
+
+ /* INPUT_MODE=1 */
+ cx25840_and_or(client, 0x401, ~0x6, 0x02);
+ break;
+
+ default:
+ cx25840_err("%d is not a valid input!\n", input);
+ return -EINVAL;
+ }
+
+ state->input = input;
+ input_change(client);
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
+{
+ u8 fmt;
+
+ switch (std) {
+ /* zero is autodetect */
+ case 0: fmt = 0x0; break;
+ /* default ntsc to ntsc-m */
+ case V4L2_STD_NTSC:
+ case V4L2_STD_NTSC_M: fmt = 0x1; break;
+ case V4L2_STD_NTSC_M_JP: fmt = 0x2; break;
+ case V4L2_STD_NTSC_443: fmt = 0x3; break;
+ case V4L2_STD_PAL: fmt = 0x4; break;
+ case V4L2_STD_PAL_M: fmt = 0x5; break;
+ case V4L2_STD_PAL_N: fmt = 0x6; break;
+ case V4L2_STD_PAL_Nc: fmt = 0x7; break;
+ case V4L2_STD_PAL_60: fmt = 0x8; break;
+ case V4L2_STD_SECAM: fmt = 0xc; break;
+ default:
+ return -ERANGE;
+ }
+
+ cx25840_and_or(client, 0x400, ~0xf, fmt);
+ cx25840_vbi_setup(client);
+ return 0;
+}
+
+v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
+{
+ /* check VID_FMT_SEL first */
+ u8 fmt = cx25840_read(client, 0x400) & 0xf;
+
+ if (!fmt) {
+ /* check AFD_FMT_STAT if set to autodetect */
+ fmt = cx25840_read(client, 0x40d) & 0xf;
+ }
+
+ switch (fmt) {
+ case 0x1: return V4L2_STD_NTSC_M;
+ case 0x2: return V4L2_STD_NTSC_M_JP;
+ case 0x3: return V4L2_STD_NTSC_443;
+ case 0x4: return V4L2_STD_PAL;
+ case 0x5: return V4L2_STD_PAL_M;
+ case 0x6: return V4L2_STD_PAL_N;
+ case 0x7: return V4L2_STD_PAL_Nc;
+ case 0x8: return V4L2_STD_PAL_60;
+ case 0xc: return V4L2_STD_SECAM;
+ default: return V4L2_STD_UNKNOWN;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+ struct cx25840_state *state = i2c_get_clientdata(client);
+
+ switch (ctrl->id) {
+ case CX25840_CID_CARDTYPE:
+ switch (ctrl->value) {
+ case CARDTYPE_PVR150:
+ case CARDTYPE_PG600:
+ state->cardtype = ctrl->value;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ set_input(client, state->input);
+ break;
+
+ case V4L2_CID_BRIGHTNESS:
+ if (ctrl->value < 0 || ctrl->value > 255) {
+ cx25840_err("invalid brightness setting %d\n",
+ ctrl->value);
+ return -ERANGE;
+ }
+
+ cx25840_write(client, 0x414, ctrl->value - 128);
+ break;
+
+ case V4L2_CID_CONTRAST:
+ if (ctrl->value < 0 || ctrl->value > 127) {
+ cx25840_err("invalid contrast setting %d\n",
+ ctrl->value);
+ return -ERANGE;
+ }
+
+ cx25840_write(client, 0x415, ctrl->value << 1);
+ break;
+
+ case V4L2_CID_SATURATION:
+ if (ctrl->value < 0 || ctrl->value > 127) {
+ cx25840_err("invalid saturation setting %d\n",
+ ctrl->value);
+ return -ERANGE;
+ }
+
+ cx25840_write(client, 0x420, ctrl->value << 1);
+ cx25840_write(client, 0x421, ctrl->value << 1);
+ break;
+
+ case V4L2_CID_HUE:
+ if (ctrl->value < -127 || ctrl->value > 127) {
+ cx25840_err("invalid hue setting %d\n", ctrl->value);
+ return -ERANGE;
+ }
+
+ cx25840_write(client, 0x422, ctrl->value);
+ break;
+
+ case V4L2_CID_AUDIO_VOLUME:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_MUTE:
+ return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
+ }
+
+ return 0;
+}
+
+static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+ struct cx25840_state *state = i2c_get_clientdata(client);
+
+ switch (ctrl->id) {
+ case CX25840_CID_CARDTYPE:
+ ctrl->value = state->cardtype;
+ break;
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = cx25840_read(client, 0x414) + 128;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = cx25840_read(client, 0x415) >> 1;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = cx25840_read(client, 0x420) >> 1;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = cx25840_read(client, 0x422);
+ break;
+ case V4L2_CID_AUDIO_VOLUME:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_MUTE:
+ return cx25840_audio(client, VIDIOC_G_CTRL, ctrl);
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+{
+ switch (fmt->type) {
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ return cx25840_vbi(client, VIDIOC_G_FMT, fmt);
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+{
+ struct v4l2_pix_format *pix;
+ int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
+ int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
+
+ switch (fmt->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ pix = &(fmt->fmt.pix);
+
+ Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4;
+ Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4;
+
+ Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
+ Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
+
+ Vlines = pix->height + (is_pal ? 4 : 7);
+
+ if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
+ (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
+ cx25840_err("%dx%d is not a valid size!\n",
+ pix->width, pix->height);
+ return -ERANGE;
+ }
+
+ HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
+ VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
+ VSC &= 0x1fff;
+
+ if (pix->width >= 385)
+ filter = 0;
+ else if (pix->width > 192)
+ filter = 1;
+ else if (pix->width > 96)
+ filter = 2;
+ else
+ filter = 3;
+
+ cx25840_dbg("decoder set size %dx%d -> scale %ux%u\n",
+ pix->width, pix->height, HSC, VSC);
+
+ /* HSCALE=HSC */
+ cx25840_write(client, 0x418, HSC & 0xff);
+ cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
+ cx25840_write(client, 0x41a, HSC >> 16);
+ /* VSCALE=VSC */
+ cx25840_write(client, 0x41c, VSC & 0xff);
+ cx25840_write(client, 0x41d, VSC >> 8);
+ /* VS_INTRLACE=1 VFILT=filter */
+ cx25840_write(client, 0x41e, 0x8 | filter);
+ break;
+
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int cx25840_command(struct i2c_client *client, unsigned int cmd,
+ void *arg)
+{
+ struct cx25840_state *state = i2c_get_clientdata(client);
+ struct v4l2_tuner *vt = arg;
+ int result = 0;
+
+ switch (cmd) {
+ case 0:
+ break;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ /* ioctls to allow direct access to the
+ * cx25840 registers for testing */
+ case VIDIOC_INT_G_REGISTER:
+ {
+ struct v4l2_register *reg = arg;
+
+ if (reg->i2c_id != I2C_DRIVERID_CX25840)
+ return -EINVAL;
+ reg->val = cx25840_read(client, reg->reg & 0x0fff);
+ break;
+ }
+
+ case VIDIOC_INT_S_REGISTER:
+ {
+ struct v4l2_register *reg = arg;
+
+ if (reg->i2c_id != I2C_DRIVERID_CX25840)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
+ break;
+ }
+#endif
+
+ case VIDIOC_INT_DECODE_VBI_LINE:
+ return cx25840_vbi(client, cmd, arg);
+
+ case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+ case AUDC_SET_INPUT:
+ result = cx25840_audio(client, cmd, arg);
+ break;
+
+ case VIDIOC_STREAMON:
+ cx25840_dbg("enable output\n");
+ cx25840_write(client, 0x115, 0x8c);
+ cx25840_write(client, 0x116, 0x07);
+ break;
+
+ case VIDIOC_STREAMOFF:
+ cx25840_dbg("disable output\n");
+ cx25840_write(client, 0x115, 0x00);
+ cx25840_write(client, 0x116, 0x00);
+ break;
+
+ case VIDIOC_LOG_STATUS:
+ log_status(client);
+ break;
+
+ case VIDIOC_G_CTRL:
+ result = get_v4lctrl(client, (struct v4l2_control *)arg);
+ break;
+
+ case VIDIOC_S_CTRL:
+ result = set_v4lctrl(client, (struct v4l2_control *)arg);
+ break;
+
+ case VIDIOC_G_STD:
+ *(v4l2_std_id *)arg = cx25840_get_v4lstd(client);
+ break;
+
+ case VIDIOC_S_STD:
+ result = set_v4lstd(client, *(v4l2_std_id *)arg);
+ break;
+
+ case VIDIOC_G_INPUT:
+ *(int *)arg = state->input;
+ break;
+
+ case VIDIOC_S_INPUT:
+ result = set_input(client, *(int *)arg);
+ break;
+
+ case VIDIOC_S_FREQUENCY:
+ input_change(client);
+ break;
+
+ case VIDIOC_G_TUNER:
+ {
+ u8 mode = cx25840_read(client, 0x804);
+ u8 pref = cx25840_read(client, 0x809) & 0xf;
+ u8 vpres = cx25840_read(client, 0x80a) & 0x10;
+ int val = 0;
+
+ vt->capability |=
+ V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+ V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+
+ vt->signal = vpres ? 0xffff : 0x0;
+
+ /* get rxsubchans and audmode */
+ if ((mode & 0xf) == 1)
+ val |= V4L2_TUNER_SUB_STEREO;
+ else
+ val |= V4L2_TUNER_SUB_MONO;
+
+ if (mode == 2 || mode == 4)
+ val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+
+ if (mode & 0x10)
+ val |= V4L2_TUNER_SUB_SAP;
+
+ vt->rxsubchans = val;
+
+ switch (pref) {
+ case 0:
+ vt->audmode = V4L2_TUNER_MODE_MONO;
+ break;
+ case 1:
+ case 2:
+ vt->audmode = V4L2_TUNER_MODE_LANG2;
+ break;
+ case 4:
+ default:
+ vt->audmode = V4L2_TUNER_MODE_STEREO;
+ }
+ break;
+ }
+
+ case VIDIOC_S_TUNER:
+ switch (vt->audmode) {
+ case V4L2_TUNER_MODE_MONO:
+ case V4L2_TUNER_MODE_LANG1:
+ /* Force PREF_MODE to MONO */
+ cx25840_and_or(client, 0x809, ~0xf, 0x00);
+ break;
+ case V4L2_TUNER_MODE_STEREO:
+ /* Force PREF_MODE to STEREO */
+ cx25840_and_or(client, 0x809, ~0xf, 0x04);
+ break;
+ case V4L2_TUNER_MODE_LANG2:
+ /* Force PREF_MODE to LANG2 */
+ cx25840_and_or(client, 0x809, ~0xf, 0x01);
+ break;
+ }
+ break;
+
+ case VIDIOC_G_FMT:
+ result = get_v4lfmt(client, (struct v4l2_format *)arg);
+ break;
+
+ case VIDIOC_S_FMT:
+ result = set_v4lfmt(client, (struct v4l2_format *)arg);
+ break;
+
+ case VIDIOC_INT_RESET:
+ cx25840_initialize(client, 0);
+ break;
+
+ case VIDIOC_INT_G_CHIP_IDENT:
+ *(enum v4l2_chip_ident *)arg =
+ V4L2_IDENT_CX25840 + ((cx25840_read(client, 0x100) >> 4) & 0xf);
+ break;
+
+ default:
+ cx25840_err("invalid ioctl %x\n", cmd);
+ return -EINVAL;
+ }
+
+ return result;
+}
+
+/* ----------------------------------------------------------------------- */
+
+struct i2c_driver i2c_driver_cx25840;
+
+static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
+ int kind)
+{
+ struct i2c_client *client;
+ struct cx25840_state *state;
+ u16 device_id;
+
+ /* Check if the adapter supports the needed features
+ * Not until kernel version 2.6.11 did the bit-algo
+ * correctly report that it would do an I2C-level xfer */
+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == 0)
+ return -ENOMEM;
+
+ memset(client, 0, sizeof(struct i2c_client));
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &i2c_driver_cx25840;
+ client->flags = I2C_CLIENT_ALLOW_USE;
+ snprintf(client->name, sizeof(client->name) - 1, "cx25840");
+
+ cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1);
+
+ device_id = cx25840_read(client, 0x101) << 8;
+ device_id |= cx25840_read(client, 0x100);
+
+ /* The high byte of the device ID should be
+ * 0x84 if chip is present */
+ if ((device_id & 0xff00) != 0x8400) {
+ cx25840_dbg("cx25840 not found\n");
+ kfree(client);
+ return 0;
+ }
+
+ cx25840_info("cx25%3x-2%x found @ 0x%x (%s)\n",
+ (device_id & 0xfff0) >> 4,
+ (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3,
+ address << 1, adapter->name);
+
+ state = kmalloc(sizeof(struct cx25840_state), GFP_KERNEL);
+ if (state == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+
+ i2c_set_clientdata(client, state);
+ memset(state, 0, sizeof(struct cx25840_state));
+ state->input = CX25840_TUNER;
+ state->audclk_freq = V4L2_AUDCLK_48_KHZ;
+ state->audio_input = AUDIO_TUNER;
+ state->cardtype = CARDTYPE_PVR150;
+
+ cx25840_initialize(client, 1);
+
+ i2c_attach_client(client);
+
+ return 0;
+}
+
+static int cx25840_attach_adapter(struct i2c_adapter *adapter)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+ if (adapter->class & I2C_CLASS_TV_ANALOG)
+#else
+ if (adapter->id == I2C_HW_B_BT848)
+#endif
+ return i2c_probe(adapter, &addr_data, &cx25840_detect_client);
+ return 0;
+}
+
+static int cx25840_detach_client(struct i2c_client *client)
+{
+ struct cx25840_state *state = i2c_get_clientdata(client);
+ int err;
+
+ err = i2c_detach_client(client);
+ if (err) {
+ return err;
+ }
+
+ kfree(state);
+ kfree(client);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+struct i2c_driver i2c_driver_cx25840 = {
+ .name = "cx25840",
+
+ .id = I2C_DRIVERID_CX25840,
+ .flags = I2C_DF_NOTIFY,
+
+ .attach_adapter = cx25840_attach_adapter,
+ .detach_client = cx25840_detach_client,
+ .command = cx25840_command,
+ .owner = THIS_MODULE,
+};
+
+
+static int __init m__init(void)
+{
+ return i2c_add_driver(&i2c_driver_cx25840);
+}
+
+static void __exit m__exit(void)
+{
+ i2c_del_driver(&i2c_driver_cx25840);
+}
+
+module_init(m__init);
+module_exit(m__exit);
+
+/* ----------------------------------------------------------------------- */
+
+static void log_status(struct i2c_client *client)
+{
+ static const char *const fmt_strs[] = {
+ "0x0",
+ "NTSC-M", "NTSC-J", "NTSC-4.43",
+ "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
+ "0x9", "0xA", "0xB",
+ "SECAM",
+ "0xD", "0xE", "0xF"
+ };
+
+ struct cx25840_state *state = i2c_get_clientdata(client);
+ u8 microctrl_vidfmt = cx25840_read(client, 0x80a);
+ u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;
+ u8 gen_stat1 = cx25840_read(client, 0x40d);
+ u8 download_ctl = cx25840_read(client, 0x803);
+ u8 mod_det_stat0 = cx25840_read(client, 0x804);
+ u8 mod_det_stat1 = cx25840_read(client, 0x805);
+ u8 audio_config = cx25840_read(client, 0x808);
+ u8 pref_mode = cx25840_read(client, 0x809);
+ u8 afc0 = cx25840_read(client, 0x80b);
+ u8 mute_ctl = cx25840_read(client, 0x8d3);
+ char *p;
+
+ cx25840_info("Video signal: %spresent\n",
+ (microctrl_vidfmt & 0x10) ? "" : "not ");
+ cx25840_info("Detected format: %s\n",
+ fmt_strs[gen_stat1 & 0xf]);
+
+ switch (mod_det_stat0) {
+ case 0x00: p = "mono"; break;
+ case 0x01: p = "stereo"; break;
+ case 0x02: p = "dual"; break;
+ case 0x04: p = "tri"; break;
+ case 0x10: p = "mono with SAP"; break;
+ case 0x11: p = "stereo with SAP"; break;
+ case 0x12: p = "dual with SAP"; break;
+ case 0x14: p = "tri with SAP"; break;
+ case 0xfe: p = "forced mode"; break;
+ default: p = "not defined";
+ }
+ cx25840_info("Detected audio mode: %s\n", p);
+
+ switch (mod_det_stat1) {
+ case 0x00: p = "not defined"; break;
+ case 0x01: p = "EIAJ"; break;
+ case 0x02: p = "A2-M"; break;
+ case 0x03: p = "A2-BG"; break;
+ case 0x04: p = "A2-DK1"; break;
+ case 0x05: p = "A2-DK2"; break;
+ case 0x06: p = "A2-DK3"; break;
+ case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
+ case 0x08: p = "AM-L"; break;
+ case 0x09: p = "NICAM-BG"; break;
+ case 0x0a: p = "NICAM-DK"; break;
+ case 0x0b: p = "NICAM-I"; break;
+ case 0x0c: p = "NICAM-L"; break;
+ case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
+ case 0x0e: p = "IF FM Radio"; break;
+ case 0x0f: p = "BTSC"; break;
+ case 0x10: p = "high-deviation FM"; break;
+ case 0x11: p = "very high-deviation FM"; break;
+ case 0xfd: p = "unknown audio standard"; break;
+ case 0xfe: p = "forced audio standard"; break;
+ case 0xff: p = "no detected audio standard"; break;
+ default: p = "not defined";
+ }
+ cx25840_info("Detected audio standard: %s\n", p);
+ cx25840_info("Audio muted: %s\n",
+ (mute_ctl & 0x2) ? "yes" : "no");
+ cx25840_info("Audio microcontroller: %s\n",
+ (download_ctl & 0x10) ? "running" : "stopped");
+
+ switch (audio_config >> 4) {
+ case 0x00: p = "undefined"; break;
+ case 0x01: p = "BTSC"; break;
+ case 0x02: p = "EIAJ"; break;
+ case 0x03: p = "A2-M"; break;
+ case 0x04: p = "A2-BG"; break;
+ case 0x05: p = "A2-DK1"; break;
+ case 0x06: p = "A2-DK2"; break;
+ case 0x07: p = "A2-DK3"; break;
+ case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
+ case 0x09: p = "AM-L"; break;
+ case 0x0a: p = "NICAM-BG"; break;
+ case 0x0b: p = "NICAM-DK"; break;
+ case 0x0c: p = "NICAM-I"; break;
+ case 0x0d: p = "NICAM-L"; break;
+ case 0x0e: p = "FM radio"; break;
+ case 0x0f: p = "automatic detection"; break;
+ default: p = "undefined";
+ }
+ cx25840_info("Configured audio standard: %s\n", p);
+
+ if ((audio_config >> 4) < 0xF) {
+ switch (audio_config & 0xF) {
+ case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
+ case 0x01: p = "MONO2 (LANGUAGE B)"; break;
+ case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
+ case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
+ case 0x04: p = "STEREO"; break;
+ case 0x05: p = "DUAL1 (AB)"; break;
+ case 0x06: p = "DUAL2 (AC) (FM)"; break;
+ case 0x07: p = "DUAL3 (BC) (FM)"; break;
+ case 0x08: p = "DUAL4 (AC) (AM)"; break;
+ case 0x09: p = "DUAL5 (BC) (AM)"; break;
+ case 0x0a: p = "SAP"; break;
+ default: p = "undefined";
+ }
+ cx25840_info("Configured audio mode: %s\n", p);
+ } else {
+ switch (audio_config & 0xF) {
+ case 0x00: p = "BG"; break;
+ case 0x01: p = "DK1"; break;
+ case 0x02: p = "DK2"; break;
+ case 0x03: p = "DK3"; break;
+ case 0x04: p = "I"; break;
+ case 0x05: p = "L"; break;
+ case 0x06: p = "BTSC"; break;
+ case 0x07: p = "EIAJ"; break;
+ case 0x08: p = "A2-M"; break;
+ case 0x09: p = "FM Radio"; break;
+ case 0x0f: p = "automatic standard and mode detection"; break;
+ default: p = "undefined";
+ }
+ cx25840_info("Configured audio system: %s\n", p);
+ }
+
+ cx25840_info("Specified standard: %s\n",
+ vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
+
+ switch (state->input) {
+ case CX25840_COMPOSITE0: p = "Composite 0"; break;
+ case CX25840_COMPOSITE1: p = "Composite 1"; break;
+ case CX25840_SVIDEO0: p = "S-Video 0"; break;
+ case CX25840_SVIDEO1: p = "S-Video 1"; break;
+ case CX25840_TUNER: p = "Tuner"; break;
+ }
+ cx25840_info("Specified input: %s\n", p);
+ cx25840_info("Specified audio input: %s\n",
+ state->audio_input == 0 ? "Tuner" : "External");
+
+ switch (state->audclk_freq) {
+ case V4L2_AUDCLK_441_KHZ: p = "44.1 kHz"; break;
+ case V4L2_AUDCLK_48_KHZ: p = "48 kHz"; break;
+ case V4L2_AUDCLK_32_KHZ: p = "32 kHz"; break;
+ default: p = "undefined";
+ }
+ cx25840_info("Specified audioclock freq: %s\n", p);
+
+ switch (pref_mode & 0xf) {
+ case 0: p = "mono/language A"; break;
+ case 1: p = "language B"; break;
+ case 2: p = "language C"; break;
+ case 3: p = "analog fallback"; break;
+ case 4: p = "stereo"; break;
+ case 5: p = "language AC"; break;
+ case 6: p = "language BC"; break;
+ case 7: p = "language AB"; break;
+ default: p = "undefined";
+ }
+ cx25840_info("Preferred audio mode: %s\n", p);
+
+ if ((audio_config & 0xf) == 0xf) {
+ switch ((afc0 >> 3) & 0x3) {
+ case 0: p = "system DK"; break;
+ case 1: p = "system L"; break;
+ case 2: p = "autodetect"; break;
+ default: p = "undefined";
+ }
+ cx25840_info("Selected 65 MHz format: %s\n", p);
+
+ switch (afc0 & 0x7) {
+ case 0: p = "chroma"; break;
+ case 1: p = "BTSC"; break;
+ case 2: p = "EIAJ"; break;
+ case 3: p = "A2-M"; break;
+ case 4: p = "autodetect"; break;
+ default: p = "undefined";
+ }
+ cx25840_info("Selected 45 MHz format: %s\n", p);
+ }
+}
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
new file mode 100644
index 0000000..df9d50a
--- /dev/null
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -0,0 +1,167 @@
+/* cx25840 firmware functions
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/firmware.h>
+#include <media/v4l2-common.h>
+
+#include "cx25840.h"
+
+#define FWFILE "v4l-cx25840.fw"
+#define FWSEND 1024
+
+#define FWDEV(x) &((x)->adapter->dev)
+
+static int fastfw = 1;
+static char *firmware = FWFILE;
+
+module_param(fastfw, bool, 0444);
+module_param(firmware, charp, 0444);
+
+MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]");
+MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]");
+
+static inline void set_i2c_delay(struct i2c_client *client, int delay)
+{
+ struct i2c_algo_bit_data *algod = client->adapter->algo_data;
+
+ /* We aren't guaranteed to be using algo_bit,
+ * so avoid the null pointer dereference
+ * and disable the 'fast firmware load' */
+ if (algod) {
+ algod->udelay = delay;
+ } else {
+ fastfw = 0;
+ }
+}
+
+static inline void start_fw_load(struct i2c_client *client)
+{
+ /* DL_ADDR_LB=0 DL_ADDR_HB=0 */
+ cx25840_write(client, 0x800, 0x00);
+ cx25840_write(client, 0x801, 0x00);
+ // DL_MAP=3 DL_AUTO_INC=0 DL_ENABLE=1
+ cx25840_write(client, 0x803, 0x0b);
+ /* AUTO_INC_DIS=1 */
+ cx25840_write(client, 0x000, 0x20);
+
+ if (fastfw)
+ set_i2c_delay(client, 3);
+}
+
+static inline void end_fw_load(struct i2c_client *client)
+{
+ if (fastfw)
+ set_i2c_delay(client, 10);
+
+ /* AUTO_INC_DIS=0 */
+ cx25840_write(client, 0x000, 0x00);
+ /* DL_ENABLE=0 */
+ cx25840_write(client, 0x803, 0x03);
+}
+
+static inline int check_fw_load(struct i2c_client *client, int size)
+{
+ /* DL_ADDR_HB DL_ADDR_LB */
+ int s = cx25840_read(client, 0x801) << 8;
+ s |= cx25840_read(client, 0x800);
+
+ if (size != s) {
+ cx25840_err("firmware %s load failed\n", firmware);
+ return -EINVAL;
+ }
+
+ cx25840_info("loaded %s firmware (%d bytes)\n", firmware, size);
+ return 0;
+}
+
+static inline int fw_write(struct i2c_client *client, u8 * data, int size)
+{
+ if (i2c_master_send(client, data, size) < size) {
+
+ if (fastfw) {
+ cx25840_err("333MHz i2c firmware load failed\n");
+ fastfw = 0;
+ set_i2c_delay(client, 10);
+
+ if (i2c_master_send(client, data, size) < size) {
+ cx25840_err
+ ("100MHz i2c firmware load failed\n");
+ return -ENOSYS;
+ }
+
+ } else {
+ cx25840_err("firmware load i2c failure\n");
+ return -ENOSYS;
+ }
+
+ }
+
+ return 0;
+}
+
+int cx25840_loadfw(struct i2c_client *client)
+{
+ const struct firmware *fw = NULL;
+ u8 buffer[4], *ptr;
+ int size, send, retval;
+
+ if (request_firmware(&fw, firmware, FWDEV(client)) != 0) {
+ cx25840_err("unable to open firmware %s\n", firmware);
+ return -EINVAL;
+ }
+
+ start_fw_load(client);
+
+ buffer[0] = 0x08;
+ buffer[1] = 0x02;
+ buffer[2] = fw->data[0];
+ buffer[3] = fw->data[1];
+ retval = fw_write(client, buffer, 4);
+
+ if (retval < 0) {
+ release_firmware(fw);
+ return retval;
+ }
+
+ size = fw->size - 2;
+ ptr = fw->data;
+ while (size > 0) {
+ ptr[0] = 0x08;
+ ptr[1] = 0x02;
+ send = size > (FWSEND - 2) ? FWSEND : size + 2;
+ retval = fw_write(client, ptr, send);
+
+ if (retval < 0) {
+ release_firmware(fw);
+ return retval;
+ }
+
+ size -= FWSEND - 2;
+ ptr += FWSEND - 2;
+ }
+
+ end_fw_load(client);
+
+ size = fw->size;
+ release_firmware(fw);
+
+ return check_fw_load(client, size);
+}
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
new file mode 100644
index 0000000..13ba4e1
--- /dev/null
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -0,0 +1,315 @@
+/* cx25840 VBI functions
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <media/v4l2-common.h>
+
+#include "cx25840.h"
+
+static inline int odd_parity(u8 c)
+{
+ c ^= (c >> 4);
+ c ^= (c >> 2);
+ c ^= (c >> 1);
+
+ return c & 1;
+}
+
+static inline int decode_vps(u8 * dst, u8 * p)
+{
+ static const u8 biphase_tbl[] = {
+ 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+ 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+ 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
+ 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
+ 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
+ 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
+ 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+ 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+ 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
+ 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
+ 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
+ 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
+ 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
+ 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
+ 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
+ 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
+ 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
+ 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
+ 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
+ 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
+ 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
+ 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
+ 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
+ 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
+ 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+ 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+ 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
+ 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
+ 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
+ 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
+ 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+ 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+ };
+
+ u8 c, err = 0;
+ int i;
+
+ for (i = 0; i < 2 * 13; i += 2) {
+ err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
+ c = (biphase_tbl[p[i + 1]] & 0xf) |
+ ((biphase_tbl[p[i]] & 0xf) << 4);
+ dst[i / 2] = c;
+ }
+
+ return err & 0xf0;
+}
+
+void cx25840_vbi_setup(struct i2c_client *client)
+{
+ v4l2_std_id std = cx25840_get_v4lstd(client);
+
+ if (std & ~V4L2_STD_NTSC) {
+ /* datasheet startup, step 8d */
+ cx25840_write(client, 0x49f, 0x11);
+
+ cx25840_write(client, 0x470, 0x84);
+ cx25840_write(client, 0x471, 0x00);
+ cx25840_write(client, 0x472, 0x2d);
+ cx25840_write(client, 0x473, 0x5d);
+
+ cx25840_write(client, 0x474, 0x24);
+ cx25840_write(client, 0x475, 0x40);
+ cx25840_write(client, 0x476, 0x24);
+ cx25840_write(client, 0x477, 0x28);
+
+ cx25840_write(client, 0x478, 0x1f);
+ cx25840_write(client, 0x479, 0x02);
+
+ if (std & V4L2_STD_SECAM) {
+ cx25840_write(client, 0x47a, 0x80);
+ cx25840_write(client, 0x47b, 0x00);
+ cx25840_write(client, 0x47c, 0x5f);
+ cx25840_write(client, 0x47d, 0x42);
+ } else {
+ cx25840_write(client, 0x47a, 0x90);
+ cx25840_write(client, 0x47b, 0x20);
+ cx25840_write(client, 0x47c, 0x63);
+ cx25840_write(client, 0x47d, 0x82);
+ }
+
+ cx25840_write(client, 0x47e, 0x0a);
+ cx25840_write(client, 0x47f, 0x01);
+ } else {
+ /* datasheet startup, step 8d */
+ cx25840_write(client, 0x49f, 0x14);
+
+ cx25840_write(client, 0x470, 0x7a);
+ cx25840_write(client, 0x471, 0x00);
+ cx25840_write(client, 0x472, 0x2d);
+ cx25840_write(client, 0x473, 0x5b);
+
+ cx25840_write(client, 0x474, 0x1a);
+ cx25840_write(client, 0x475, 0x70);
+ cx25840_write(client, 0x476, 0x1e);
+ cx25840_write(client, 0x477, 0x1e);
+
+ cx25840_write(client, 0x478, 0x1f);
+ cx25840_write(client, 0x479, 0x02);
+ cx25840_write(client, 0x47a, 0x50);
+ cx25840_write(client, 0x47b, 0x66);
+
+ cx25840_write(client, 0x47c, 0x1f);
+ cx25840_write(client, 0x47d, 0x7c);
+ cx25840_write(client, 0x47e, 0x08);
+ cx25840_write(client, 0x47f, 0x00);
+ }
+}
+
+int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+ struct v4l2_format *fmt;
+ struct v4l2_sliced_vbi_format *svbi;
+
+ switch (cmd) {
+ case VIDIOC_G_FMT:
+ {
+ static u16 lcr2vbi[] = {
+ 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
+ 0, V4L2_SLICED_WSS_625, 0, /* 4 */
+ V4L2_SLICED_CAPTION_525, /* 6 */
+ 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
+ 0, 0, 0, 0
+ };
+ int i;
+
+ fmt = arg;
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ memset(svbi, 0, sizeof(*svbi));
+ /* we're done if raw VBI is active */
+ if ((cx25840_read(client, 0x404) & 0x10) == 0)
+ break;
+
+ for (i = 7; i <= 23; i++) {
+ u8 v = cx25840_read(client, 0x424 + i - 7);
+
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |=
+ svbi->service_lines[0][i] | svbi->service_lines[1][i];
+ }
+ break;
+ }
+
+ case VIDIOC_S_FMT:
+ {
+ int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
+ int vbi_offset = is_pal ? 1 : 0;
+ int i, x;
+ u8 lcr[24];
+
+ fmt = arg;
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ if (svbi->service_set == 0) {
+ /* raw VBI */
+ memset(svbi, 0, sizeof(*svbi));
+
+ /* Setup VBI */
+ cx25840_vbi_setup(client);
+
+ /* VBI Offset */
+ cx25840_write(client, 0x47f, vbi_offset);
+ cx25840_write(client, 0x404, 0x2e);
+ break;
+ }
+
+ for (x = 0; x <= 23; x++)
+ lcr[x] = 0x00;
+
+ /* Setup VBI */
+ cx25840_vbi_setup(client);
+
+ /* Sliced VBI */
+ cx25840_write(client, 0x404, 0x36); /* Ancillery data */
+ cx25840_write(client, 0x406, 0x13);
+ cx25840_write(client, 0x47f, vbi_offset);
+
+ if (is_pal) {
+ for (i = 0; i <= 6; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ } else {
+ for (i = 0; i <= 9; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+
+ for (i = 22; i <= 23; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ }
+
+ for (i = 7; i <= 23; i++) {
+ for (x = 0; x <= 1; x++) {
+ switch (svbi->service_lines[1-x][i]) {
+ case V4L2_SLICED_TELETEXT_B:
+ lcr[i] |= 1 << (4 * x);
+ break;
+ case V4L2_SLICED_WSS_625:
+ lcr[i] |= 4 << (4 * x);
+ break;
+ case V4L2_SLICED_CAPTION_525:
+ lcr[i] |= 6 << (4 * x);
+ break;
+ case V4L2_SLICED_VPS:
+ lcr[i] |= 9 << (4 * x);
+ break;
+ }
+ }
+ }
+
+ for (x = 1, i = 0x424; i <= 0x434; i++, x++) {
+ cx25840_write(client, i, lcr[6 + x]);
+ }
+
+ cx25840_write(client, 0x43c, 0x16);
+
+ if (is_pal) {
+ cx25840_write(client, 0x474, 0x2a);
+ } else {
+ cx25840_write(client, 0x474, 0x1a + 6);
+ }
+ break;
+ }
+
+ case VIDIOC_INT_DECODE_VBI_LINE:
+ {
+ struct v4l2_decode_vbi_line *vbi = arg;
+ u8 *p = vbi->p;
+ int id1, id2, l, err = 0;
+
+ if (p[0] || p[1] != 0xff || p[2] != 0xff ||
+ (p[3] != 0x55 && p[3] != 0x91)) {
+ vbi->line = vbi->type = 0;
+ break;
+ }
+
+ p += 4;
+ id1 = p[-1];
+ id2 = p[0] & 0xf;
+ l = p[2] & 0x3f;
+ l += 5;
+ p += 4;
+
+ switch (id2) {
+ case 1:
+ id2 = V4L2_SLICED_TELETEXT_B;
+ break;
+ case 4:
+ id2 = V4L2_SLICED_WSS_625;
+ break;
+ case 6:
+ id2 = V4L2_SLICED_CAPTION_525;
+ err = !odd_parity(p[0]) || !odd_parity(p[1]);
+ break;
+ case 9:
+ id2 = V4L2_SLICED_VPS;
+ if (decode_vps(p, p) != 0) {
+ err = 1;
+ }
+ break;
+ default:
+ id2 = 0;
+ err = 1;
+ break;
+ }
+
+ vbi->type = err ? 0 : id2;
+ vbi->line = err ? 0 : l;
+ vbi->is_second_field = err ? 0 : (id1 == 0x55);
+ vbi->p = p;
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h
new file mode 100644
index 0000000..5c3f063
--- /dev/null
+++ b/drivers/media/video/cx25840/cx25840.h
@@ -0,0 +1,85 @@
+/* cx25840 API header
+ *
+ * Copyright (C) 2003-2004 Chris Kennedy
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _CX25840_H_
+#define _CX25840_H_
+
+
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+
+extern int cx25840_debug;
+
+#define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \
+ printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+#define cx25840_err(fmt, arg...) do { \
+ printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+#define cx25840_info(fmt, arg...) do { \
+ printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+#define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0)
+
+enum cx25840_cardtype {
+ CARDTYPE_PVR150,
+ CARDTYPE_PG600
+};
+
+enum cx25840_input {
+ CX25840_TUNER,
+ CX25840_COMPOSITE0,
+ CX25840_COMPOSITE1,
+ CX25840_SVIDEO0,
+ CX25840_SVIDEO1
+};
+
+struct cx25840_state {
+ enum cx25840_cardtype cardtype;
+ enum cx25840_input input;
+ int audio_input;
+ enum v4l2_audio_clock_freq audclk_freq;
+};
+
+/* ----------------------------------------------------------------------- */
+/* cx25850-core.c */
+int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
+int cx25840_write4(struct i2c_client *client, u16 addr, u32 value);
+u8 cx25840_read(struct i2c_client *client, u16 addr);
+u32 cx25840_read4(struct i2c_client *client, u16 addr);
+int cx25840_and_or(struct i2c_client *client, u16 addr, u8 mask, u8 value);
+v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client);
+
+/* ----------------------------------------------------------------------- */
+/* cx25850-firmware.c */
+int cx25840_loadfw(struct i2c_client *client);
+
+/* ----------------------------------------------------------------------- */
+/* cx25850-audio.c */
+int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg);
+
+/* ----------------------------------------------------------------------- */
+/* cx25850-vbi.c */
+void cx25840_vbi_setup(struct i2c_client *client);
+int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg);
+
+#endif
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 9cce91e..99ea955 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -439,9 +439,6 @@ static int dvb_register(struct cx8802_dev *dev)
/* Put the analog decoder in standby to keep it quiet */
cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
- /* Put the analog decoder in standby to keep it quiet */
- cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
-
/* register everything */
return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
}
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 32c49df..9b94f77 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -120,9 +120,6 @@ static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
if (buf[1]==0xff)
return 0;
- /* avoid fast reapeating */
- if (buf[1]==ir->old)
- return 0;
ir->old=buf[1];
/* Rearranges bits to the right order */
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index ed81934..5abfc0fb 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -221,24 +221,99 @@ static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
[ 24 ] = KEY_MUTE // mute/unmute
};
+static IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = {
+ [0x00] = KEY_KP0,
+ [0x01] = KEY_KP1,
+ [0x02] = KEY_KP2,
+ [0x03] = KEY_KP3,
+ [0x04] = KEY_KP4,
+ [0x05] = KEY_KP5,
+ [0x06] = KEY_KP6,
+ [0x07] = KEY_KP7,
+ [0x08] = KEY_KP8,
+ [0x09] = KEY_KP9,
+ [0x0a] = KEY_TV,
+ [0x0b] = KEY_AUX,
+ [0x0c] = KEY_DVD,
+ [0x0d] = KEY_POWER,
+ [0x0e] = KEY_MHP, /* labelled 'Picture' */
+ [0x0f] = KEY_AUDIO,
+ [0x10] = KEY_INFO,
+ [0x11] = KEY_F13, /* 16:9 */
+ [0x12] = KEY_F14, /* 14:9 */
+ [0x13] = KEY_EPG,
+ [0x14] = KEY_EXIT,
+ [0x15] = KEY_MENU,
+ [0x16] = KEY_UP,
+ [0x17] = KEY_DOWN,
+ [0x18] = KEY_LEFT,
+ [0x19] = KEY_RIGHT,
+ [0x1a] = KEY_ENTER,
+ [0x1b] = KEY_CHANNELUP,
+ [0x1c] = KEY_CHANNELDOWN,
+ [0x1d] = KEY_VOLUMEUP,
+ [0x1e] = KEY_VOLUMEDOWN,
+ [0x1f] = KEY_RED,
+ [0x20] = KEY_GREEN,
+ [0x21] = KEY_YELLOW,
+ [0x22] = KEY_BLUE,
+ [0x23] = KEY_SUBTITLE,
+ [0x24] = KEY_F15, /* AD */
+ [0x25] = KEY_TEXT,
+ [0x26] = KEY_MUTE,
+ [0x27] = KEY_REWIND,
+ [0x28] = KEY_STOP,
+ [0x29] = KEY_PLAY,
+ [0x2a] = KEY_FASTFORWARD,
+ [0x2b] = KEY_F16, /* chapter */
+ [0x2c] = KEY_PAUSE,
+ [0x2d] = KEY_PLAY,
+ [0x2e] = KEY_RECORD,
+ [0x2f] = KEY_F17, /* picture in picture */
+ [0x30] = KEY_KPPLUS, /* zoom in */
+ [0x31] = KEY_KPMINUS, /* zoom out */
+ [0x32] = KEY_F18, /* capture */
+ [0x33] = KEY_F19, /* web */
+ [0x34] = KEY_EMAIL,
+ [0x35] = KEY_PHONE,
+ [0x36] = KEY_PC
+};
+
struct IR {
struct bttv_sub_device *sub;
struct input_dev *input;
struct ir_input_state ir;
char name[32];
char phys[32];
+
+ /* Usual gpio signalling */
+
u32 mask_keycode;
u32 mask_keydown;
u32 mask_keyup;
-
- int polling;
+ u32 polling;
u32 last_gpio;
struct work_struct work;
struct timer_list timer;
+
+ /* RC5 gpio */
+
+ u32 rc5_gpio;
+ struct timer_list timer_end; /* timer_end for code completion */
+ struct timer_list timer_keyup; /* timer_end for key release */
+ u32 last_rc5; /* last good rc5 code */
+ u32 last_bit; /* last raw bit seen */
+ u32 code; /* raw code under construction */
+ struct timeval base_time; /* time of last seen code */
+ int active; /* building raw code */
};
static int debug;
module_param(debug, int, 0644); /* debug level (0,1,2) */
+static int repeat_delay = 500;
+module_param(repeat_delay, int, 0644);
+static int repeat_period = 33;
+module_param(repeat_period, int, 0644);
#define DEVNAME "ir-kbd-gpio"
#define dprintk(fmt, arg...) if (debug) \
@@ -254,7 +329,7 @@ static struct bttv_sub_driver driver = {
.probe = ir_probe,
.remove = ir_remove,
},
- .gpio_irq = ir_irq,
+ .gpio_irq = ir_irq,
};
/* ---------------------------------------------------------------------- */
@@ -327,6 +402,173 @@ static void ir_work(void *data)
mod_timer(&ir->timer, timeout);
}
+/* ---------------------------------------------------------------*/
+
+static int rc5_remote_gap = 885;
+module_param(rc5_remote_gap, int, 0644);
+static int rc5_key_timeout = 200;
+module_param(rc5_key_timeout, int, 0644);
+
+#define RC5_START(x) (((x)>>12)&3)
+#define RC5_TOGGLE(x) (((x)>>11)&1)
+#define RC5_ADDR(x) (((x)>>6)&31)
+#define RC5_INSTR(x) ((x)&63)
+
+/* decode raw bit pattern to RC5 code */
+static u32 rc5_decode(unsigned int code)
+{
+ unsigned int org_code = code;
+ unsigned int pair;
+ unsigned int rc5 = 0;
+ int i;
+
+ code = (code << 1) | 1;
+ for (i = 0; i < 14; ++i) {
+ pair = code & 0x3;
+ code >>= 2;
+
+ rc5 <<= 1;
+ switch (pair) {
+ case 0:
+ case 2:
+ break;
+ case 1:
+ rc5 |= 1;
+ break;
+ case 3:
+ dprintk("bad code: %x\n", org_code);
+ return 0;
+ }
+ }
+ dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
+ "instr=%x\n", rc5, org_code, RC5_START(rc5),
+ RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
+ return rc5;
+}
+
+static int ir_rc5_irq(struct bttv_sub_device *sub)
+{
+ struct IR *ir = dev_get_drvdata(&sub->dev);
+ struct timeval tv;
+ u32 gpio;
+ u32 gap;
+ unsigned long current_jiffies, timeout;
+
+ /* read gpio port */
+ gpio = bttv_gpio_read(ir->sub->core);
+
+ /* remote IRQ? */
+ if (!(gpio & 0x20))
+ return 0;
+
+ /* get time of bit */
+ current_jiffies = jiffies;
+ do_gettimeofday(&tv);
+
+ /* avoid overflow with gap >1s */
+ if (tv.tv_sec - ir->base_time.tv_sec > 1) {
+ gap = 200000;
+ } else {
+ gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
+ tv.tv_usec - ir->base_time.tv_usec;
+ }
+
+ /* active code => add bit */
+ if (ir->active) {
+ /* only if in the code (otherwise spurious IRQ or timer
+ late) */
+ if (ir->last_bit < 28) {
+ ir->last_bit = (gap - rc5_remote_gap / 2) /
+ rc5_remote_gap;
+ ir->code |= 1 << ir->last_bit;
+ }
+ /* starting new code */
+ } else {
+ ir->active = 1;
+ ir->code = 0;
+ ir->base_time = tv;
+ ir->last_bit = 0;
+
+ timeout = current_jiffies + (500 + 30 * HZ) / 1000;
+ mod_timer(&ir->timer_end, timeout);
+ }
+
+ /* toggle GPIO pin 4 to reset the irq */
+ bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4));
+ bttv_gpio_write(ir->sub->core, gpio | (1 << 4));
+ return 1;
+}
+
+static void ir_rc5_timer_end(unsigned long data)
+{
+ struct IR *ir = (struct IR *)data;
+ struct timeval tv;
+ unsigned long current_jiffies, timeout;
+ u32 gap;
+
+ /* get time */
+ current_jiffies = jiffies;
+ do_gettimeofday(&tv);
+
+ /* avoid overflow with gap >1s */
+ if (tv.tv_sec - ir->base_time.tv_sec > 1) {
+ gap = 200000;
+ } else {
+ gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
+ tv.tv_usec - ir->base_time.tv_usec;
+ }
+
+ /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
+ if (gap < 28000) {
+ dprintk("spurious timer_end\n");
+ return;
+ }
+
+ ir->active = 0;
+ if (ir->last_bit < 20) {
+ /* ignore spurious codes (caused by light/other remotes) */
+ dprintk("short code: %x\n", ir->code);
+ } else {
+ u32 rc5 = rc5_decode(ir->code);
+
+ /* two start bits? */
+ if (RC5_START(rc5) != 3) {
+ dprintk("rc5 start bits invalid: %u\n", RC5_START(rc5));
+
+ /* right address? */
+ } else if (RC5_ADDR(rc5) == 0x0) {
+ u32 toggle = RC5_TOGGLE(rc5);
+ u32 instr = RC5_INSTR(rc5);
+
+ /* Good code, decide if repeat/repress */
+ if (toggle != RC5_TOGGLE(ir->last_rc5) ||
+ instr != RC5_INSTR(ir->last_rc5)) {
+ dprintk("instruction %x, toggle %x\n", instr,
+ toggle);
+ ir_input_nokey(ir->input, &ir->ir);
+ ir_input_keydown(ir->input, &ir->ir, instr,
+ instr);
+ }
+
+ /* Set/reset key-up timer */
+ timeout = current_jiffies + (500 + rc5_key_timeout
+ * HZ) / 1000;
+ mod_timer(&ir->timer_keyup, timeout);
+
+ /* Save code for repeat test */
+ ir->last_rc5 = rc5;
+ }
+ }
+}
+
+static void ir_rc5_timer_keyup(unsigned long data)
+{
+ struct IR *ir = (struct IR *)data;
+
+ dprintk("key released\n");
+ ir_input_nokey(ir->input, &ir->ir);
+}
+
/* ---------------------------------------------------------------------- */
static int ir_probe(struct device *dev)
@@ -400,6 +642,12 @@ static int ir_probe(struct device *dev)
ir->mask_keyup = 0x006000;
ir->polling = 50; // ms
break;
+ case BTTV_BOARD_NEBULA_DIGITV:
+ ir_codes = ir_codes_nebula;
+ driver.any_irq = ir_rc5_irq;
+ driver.gpio_irq = NULL;
+ ir->rc5_gpio = 1;
+ break;
}
if (NULL == ir_codes) {
kfree(ir);
@@ -407,9 +655,17 @@ static int ir_probe(struct device *dev)
return -ENODEV;
}
- /* init hardware-specific stuff */
- bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0);
- ir->sub = sub;
+ if (ir->rc5_gpio) {
+ u32 gpio;
+ /* enable remote irq */
+ bttv_gpio_inout(sub->core, (1 << 4), 1 << 4);
+ gpio = bttv_gpio_read(sub->core);
+ bttv_gpio_write(sub->core, gpio & ~(1 << 4));
+ bttv_gpio_write(sub->core, gpio | (1 << 4));
+ } else {
+ /* init hardware-specific stuff */
+ bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0);
+ }
/* init input device */
snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
@@ -417,6 +673,7 @@ static int ir_probe(struct device *dev)
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(sub->core->pci));
+ ir->sub = sub;
ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
input_dev->name = ir->name;
input_dev->phys = ir->phys;
@@ -437,11 +694,25 @@ static int ir_probe(struct device *dev)
ir->timer.function = ir_timer;
ir->timer.data = (unsigned long)ir;
schedule_work(&ir->work);
+ } else if (ir->rc5_gpio) {
+ /* set timer_end for code completion */
+ init_timer(&ir->timer_end);
+ ir->timer_end.function = ir_rc5_timer_end;
+ ir->timer_end.data = (unsigned long)ir;
+
+ init_timer(&ir->timer_keyup);
+ ir->timer_keyup.function = ir_rc5_timer_keyup;
+ ir->timer_keyup.data = (unsigned long)ir;
}
/* all done */
dev_set_drvdata(dev, ir);
input_register_device(ir->input);
+ printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
+
+ /* the remote isn't as bouncy as a keyboard */
+ ir->input->rep[REP_DELAY] = repeat_delay;
+ ir->input->rep[REP_PERIOD] = repeat_period;
return 0;
}
@@ -454,6 +725,15 @@ static int ir_remove(struct device *dev)
del_timer(&ir->timer);
flush_scheduled_work();
}
+ if (ir->rc5_gpio) {
+ u32 gpio;
+
+ del_timer(&ir->timer_end);
+ flush_scheduled_work();
+
+ gpio = bttv_gpio_read(ir->sub->core);
+ bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4));
+ }
input_unregister_device(ir->input);
kfree(ir);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 0085567..801c736 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -183,6 +183,58 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
+/* The new pinnacle PCTV remote (with the colored buttons)
+ *
+ * Ricardo Cerqueira <v4l@cerqueira.org>
+ */
+
+int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+ unsigned char b[4];
+ unsigned int start = 0,parity = 0,code = 0;
+
+ /* poll IR chip */
+ if (4 != i2c_master_recv(&ir->c,b,4)) {
+ dprintk(2,"read error\n");
+ return -EIO;
+ }
+
+ for (start = 0; start<4; start++) {
+ if (b[start] == 0x80) {
+ code=b[(start+3)%4];
+ parity=b[(start+2)%4];
+ }
+ }
+
+ /* Empty Request */
+ if (parity==0)
+ return 0;
+
+ /* Repeating... */
+ if (ir->old == parity)
+ return 0;
+
+
+ ir->old = parity;
+
+ /* Reduce code value to fit inside IR_KEYTAB_SIZE
+ *
+ * this is the only value that results in 42 unique
+ * codes < 128
+ */
+
+ code %= 0x88;
+
+ *ir_raw = code;
+ *ir_key = code;
+
+ dprintk(1,"Pinnacle PCTV key %02x\n", code);
+
+ return 1;
+}
+
+EXPORT_SYMBOL_GPL(get_key_pinnacle);
+
/* ----------------------------------------------------------------------- */
static void ir_key_poll(struct IR_i2c *ir)
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
new file mode 100644
index 0000000..0235cef
--- /dev/null
+++ b/drivers/media/video/saa7115.c
@@ -0,0 +1,1376 @@
+/* saa7115 - Philips SAA7114/SAA7115 video decoder driver
+ *
+ * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
+ * the saa7111 driver by Dave Perks.
+ *
+ * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+ * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
+ *
+ * Slight changes for video timing and attachment output by
+ * Wolfgang Scherr <scherr@net4you.net>
+ *
+ * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
+ * by Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
+ * (2/17/2003)
+ *
+ * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+
+MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver");
+MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil");
+MODULE_LICENSE("GPL");
+
+static int debug = 0;
+module_param(debug, int, 0644);
+
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+#define saa7115_dbg(fmt,arg...) \
+ do { \
+ if (debug) \
+ printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); \
+ } while (0)
+
+#define saa7115_err(fmt, arg...) do { \
+ printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+#define saa7115_info(fmt, arg...) do { \
+ printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
+
+
+I2C_CLIENT_INSMOD;
+
+struct saa7115_state {
+ v4l2_std_id std;
+ int input;
+ int enable;
+ int bright;
+ int contrast;
+ int hue;
+ int sat;
+ enum v4l2_chip_ident ident;
+ enum v4l2_audio_clock_freq audclk_freq;
+};
+
+/* ----------------------------------------------------------------------- */
+
+static inline int saa7115_write(struct i2c_client *client, u8 reg, u8 value)
+{
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static int saa7115_writeregs(struct i2c_client *client, const unsigned char *regs)
+{
+ unsigned char reg, data;
+
+ while (*regs != 0x00) {
+ reg = *(regs++);
+ data = *(regs++);
+ if (saa7115_write(client, reg, data) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static inline int saa7115_read(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* If a value differs from the Hauppauge driver values, then the comment starts with
+ 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
+ Hauppauge driver sets. */
+
+static const unsigned char saa7115_init_auto_input[] = {
+ 0x01, 0x48, /* white peak control disabled */
+ 0x03, 0x20, /* was 0x30. 0x20: long vertical blanking */
+ 0x04, 0x90, /* analog gain set to 0 */
+ 0x05, 0x90, /* analog gain set to 0 */
+ 0x06, 0xeb, /* horiz sync begin = -21 */
+ 0x07, 0xe0, /* horiz sync stop = -17 */
+ 0x0a, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
+ 0x0b, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
+ 0x0c, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
+ 0x0d, 0x00, /* chrominance hue control */
+ 0x0f, 0x00, /* chrominance gain control: use automicatic mode */
+ 0x10, 0x06, /* chrominance/luminance control: active adaptive combfilter */
+ 0x11, 0x00, /* delay control */
+ 0x12, 0x9d, /* RTS0 output control: VGATE */
+ 0x13, 0x80, /* X-port output control: ITU656 standard mode, RTCO output enable RTCE */
+ 0x14, 0x00, /* analog/ADC/auto compatibility control */
+ 0x18, 0x40, /* raw data gain 0x00 = nominal */
+ 0x19, 0x80, /* raw data offset 0x80 = 0 LSB */
+ 0x1a, 0x77, /* color killer level control 0x77 = recommended */
+ 0x1b, 0x42, /* misc chroma control 0x42 = recommended */
+ 0x1c, 0xa9, /* combfilter control 0xA9 = recommended */
+ 0x1d, 0x01, /* combfilter control 0x01 = recommended */
+ 0x88, 0xd0, /* reset device */
+ 0x88, 0xf0, /* set device programmed, all in operational mode */
+ 0x00, 0x00
+};
+
+static const unsigned char saa7115_cfg_reset_scaler[] = {
+ 0x87, 0x00, /* disable I-port output */
+ 0x88, 0xd0, /* reset scaler */
+ 0x88, 0xf0, /* activate scaler */
+ 0x87, 0x01, /* enable I-port output */
+ 0x00, 0x00
+};
+
+/* ============== SAA7715 VIDEO templates ============= */
+
+static const unsigned char saa7115_cfg_60hz_fullres_x[] = {
+ 0xcc, 0xd0, /* hsize low (output), hor. output window size = 0x2d0 = 720 */
+ 0xcd, 0x02, /* hsize hi (output) */
+
+ /* Why not in 60hz-Land, too? */
+ 0xd0, 0x01, /* downscale = 1 */
+ 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */
+ 0xd9, 0x04,
+ 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
+ 0xdd, 0x02, /* H-scaling incr chroma */
+
+ 0x00, 0x00
+};
+static const unsigned char saa7115_cfg_60hz_fullres_y[] = {
+ 0xce, 0xf8, /* vsize low (output), ver. output window size = 248 (but 60hz is 240?) */
+ 0xcf, 0x00, /* vsize hi (output) */
+
+ /* Why not in 60hz-Land, too? */
+ 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */
+ 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */
+
+ 0xe0, 0x00, /* V-scaling incr luma low */
+ 0xe1, 0x04, /* " hi */
+ 0xe2, 0x00, /* V-scaling incr chroma low */
+ 0xe3, 0x04, /* " hi */
+
+ 0x00, 0x00
+};
+
+static const unsigned char saa7115_cfg_60hz_video[] = {
+ 0x80, 0x00, /* reset tasks */
+ 0x88, 0xd0, /* reset scaler */
+
+ 0x15, 0x03, /* VGATE pulse start */
+ 0x16, 0x11, /* VGATE pulse stop */
+ 0x17, 0x9c, /* VGATE MSB and other values */
+
+ 0x08, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
+ 0x0e, 0x07, /* lots of different stuff... video autodetection is on */
+
+ 0x5a, 0x06, /* Vertical offset, standard 60hz value for ITU656 line counting */
+
+ /* Task A */
+ 0x90, 0x80, /* Task Handling Control */
+ 0x91, 0x48, /* X-port formats/config */
+ 0x92, 0x40, /* Input Ref. signal Def. */
+ 0x93, 0x84, /* I-port config */
+ 0x94, 0x01, /* hoffset low (input), 0x0002 is minimum */
+ 0x95, 0x00, /* hoffset hi (input) */
+ 0x96, 0xd0, /* hsize low (input), 0x02d0 = 720 */
+ 0x97, 0x02, /* hsize hi (input) */
+ 0x98, 0x05, /* voffset low (input) */
+ 0x99, 0x00, /* voffset hi (input) */
+ 0x9a, 0x0c, /* vsize low (input), 0x0c = 12 */
+ 0x9b, 0x00, /* vsize hi (input) */
+ 0x9c, 0xa0, /* hsize low (output), 0x05a0 = 1440 */
+ 0x9d, 0x05, /* hsize hi (output) */
+ 0x9e, 0x0c, /* vsize low (output), 0x0c = 12 */
+ 0x9f, 0x00, /* vsize hi (output) */
+
+ /* Task B */
+ 0xc0, 0x00, /* Task Handling Control */
+ 0xc1, 0x08, /* X-port formats/config */
+ 0xc2, 0x00, /* Input Ref. signal Def. */
+ 0xc3, 0x80, /* I-port config */
+ 0xc4, 0x02, /* hoffset low (input), 0x0002 is minimum */
+ 0xc5, 0x00, /* hoffset hi (input) */
+ 0xc6, 0xd0, /* hsize low (input), 0x02d0 = 720 */
+ 0xc7, 0x02, /* hsize hi (input) */
+ 0xc8, 0x12, /* voffset low (input), 0x12 = 18 */
+ 0xc9, 0x00, /* voffset hi (input) */
+ 0xca, 0xf8, /* vsize low (input), 0xf8 = 248 */
+ 0xcb, 0x00, /* vsize hi (input) */
+ 0xcc, 0xd0, /* hsize low (output), 0x02d0 = 720 */
+ 0xcd, 0x02, /* hsize hi (output) */
+
+ 0xf0, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
+ 0xf1, 0x05, /* low bit with 0xF0 */
+ 0xf5, 0xad, /* Set pulse generator register */
+ 0xf6, 0x01,
+
+ 0x87, 0x00, /* Disable I-port output */
+ 0x88, 0xd0, /* reset scaler */
+ 0x80, 0x20, /* Activate only task "B", continuous mode (was 0xA0) */
+ 0x88, 0xf0, /* activate scaler */
+ 0x87, 0x01, /* Enable I-port output */
+ 0x00, 0x00
+};
+
+static const unsigned char saa7115_cfg_50hz_fullres_x[] = {
+ 0xcc, 0xd0, /* hsize low (output), 720 same as 60hz */
+ 0xcd, 0x02, /* hsize hi (output) */
+
+ 0xd0, 0x01, /* down scale = 1 */
+ 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */
+ 0xd9, 0x04,
+ 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
+ 0xdd, 0x02, /* H-scaling incr chroma */
+
+ 0x00, 0x00
+};
+static const unsigned char saa7115_cfg_50hz_fullres_y[] = {
+ 0xce, 0x20, /* vsize low (output), 0x0120 = 288 */
+ 0xcf, 0x01, /* vsize hi (output) */
+
+ 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */
+ 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */
+
+ 0xe0, 0x00, /* V-scaling incr luma low */
+ 0xe1, 0x04, /* " hi */
+ 0xe2, 0x00, /* V-scaling incr chroma low */
+ 0xe3, 0x04, /* " hi */
+
+ 0x00, 0x00
+};
+
+static const unsigned char saa7115_cfg_50hz_video[] = {
+ 0x80, 0x00, /* reset tasks */
+ 0x88, 0xd0, /* reset scaler */
+
+ 0x15, 0x37, /* VGATE start */
+ 0x16, 0x16, /* VGATE stop */
+ 0x17, 0x99, /* VGATE MSB and other values */
+
+ 0x08, 0x28, /* 0x28 = PAL */
+ 0x0e, 0x07, /* chrominance control 1 */
+
+ 0x5a, 0x03, /* Vertical offset, standard 50hz value */
+
+ /* Task A */
+ 0x90, 0x81, /* Task Handling Control */
+ 0x91, 0x48, /* X-port formats/config */
+ 0x92, 0x40, /* Input Ref. signal Def. */
+ 0x93, 0x84, /* I-port config */
+ /* This is weird: the datasheet says that you should use 2 as the minimum value, */
+ /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
+ 0x94, 0x00, /* hoffset low (input), 0x0002 is minimum */
+ 0x95, 0x00, /* hoffset hi (input) */
+ 0x96, 0xd0, /* hsize low (input), 0x02d0 = 720 */
+ 0x97, 0x02, /* hsize hi (input) */
+ 0x98, 0x03, /* voffset low (input) */
+ 0x99, 0x00, /* voffset hi (input) */
+ 0x9a, 0x12, /* vsize low (input), 0x12 = 18 */
+ 0x9b, 0x00, /* vsize hi (input) */
+ 0x9c, 0xa0, /* hsize low (output), 0x05a0 = 1440 */
+ 0x9d, 0x05, /* hsize hi (output) */
+ 0x9e, 0x12, /* vsize low (output), 0x12 = 18 */
+ 0x9f, 0x00, /* vsize hi (output) */
+
+ /* Task B */
+ 0xc0, 0x00, /* Task Handling Control */
+ 0xc1, 0x08, /* X-port formats/config */
+ 0xc2, 0x00, /* Input Ref. signal Def. */
+ 0xc3, 0x80, /* I-port config */
+ 0xc4, 0x00, /* hoffset low (input), 0x0002 is minimum. See comment at 0x94 above. */
+ 0xc5, 0x00, /* hoffset hi (input) */
+ 0xc6, 0xd0, /* hsize low (input), 0x02d0 = 720 */
+ 0xc7, 0x02, /* hsize hi (input) */
+ 0xc8, 0x16, /* voffset low (input), 0x16 = 22 */
+ 0xc9, 0x00, /* voffset hi (input) */
+ 0xca, 0x20, /* vsize low (input), 0x0120 = 288 */
+ 0xcb, 0x01, /* vsize hi (input) */
+ 0xcc, 0xd0, /* hsize low (output), 0x02d0 = 720 */
+ 0xcd, 0x02, /* hsize hi (output) */
+ 0xce, 0x20, /* vsize low (output), 0x0120 = 288 */
+ 0xcf, 0x01, /* vsize hi (output) */
+
+ 0xf0, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
+ 0xf1, 0x05, /* low bit with 0xF0, (was 0x05) */
+ 0xf5, 0xb0, /* Set pulse generator register */
+ 0xf6, 0x01,
+
+ 0x87, 0x00, /* Disable I-port output */
+ 0x88, 0xd0, /* reset scaler (was 0xD0) */
+ 0x80, 0x20, /* Activate only task "B" */
+ 0x88, 0xf0, /* activate scaler */
+ 0x87, 0x01, /* Enable I-port output */
+ 0x00, 0x00
+};
+
+/* ============== SAA7715 VIDEO templates (end) ======= */
+
+static const unsigned char saa7115_cfg_vbi_on[] = {
+ 0x80, 0x00, /* reset tasks */
+ 0x88, 0xd0, /* reset scaler */
+ 0x80, 0x30, /* Activate both tasks */
+ 0x88, 0xf0, /* activate scaler */
+ 0x87, 0x01, /* Enable I-port output */
+ 0x00, 0x00
+};
+
+static const unsigned char saa7115_cfg_vbi_off[] = {
+ 0x80, 0x00, /* reset tasks */
+ 0x88, 0xd0, /* reset scaler */
+ 0x80, 0x20, /* Activate only task "B" */
+ 0x88, 0xf0, /* activate scaler */
+ 0x87, 0x01, /* Enable I-port output */
+ 0x00, 0x00
+};
+
+static const unsigned char saa7115_init_misc[] = {
+ 0x38, 0x03, /* audio stuff */
+ 0x39, 0x10,
+ 0x3a, 0x08,
+
+ 0x81, 0x01, /* reg 0x15,0x16 define blanking window */
+ 0x82, 0x00,
+ 0x83, 0x01, /* I port settings */
+ 0x84, 0x20,
+ 0x85, 0x21,
+ 0x86, 0xc5,
+ 0x87, 0x01,
+
+ /* Task A */
+ 0xa0, 0x01, /* down scale = 1 */
+ 0xa1, 0x00, /* prescale accumulation length = 1 */
+ 0xa2, 0x00, /* dc gain and fir prefilter control */
+ 0xa4, 0x80, /* Lum Brightness, nominal value = 0x80 */
+ 0xa5, 0x40, /* Lum contrast, nominal value = 0x40 */
+ 0xa6, 0x40, /* Chroma satur. nominal value = 0x80 */
+ 0xa8, 0x00, /* hor lum scaling 0x0200 = 2 zoom */
+ 0xa9, 0x02, /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
+ 0xaa, 0x00, /* H-phase offset Luma = 0 */
+ 0xac, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
+ 0xad, 0x01, /* H-scaling incr chroma */
+ 0xae, 0x00, /* H-phase offset chroma. must be offset luma / 2 */
+
+ 0xb0, 0x00, /* V-scaling incr luma low */
+ 0xb1, 0x04, /* " hi */
+ 0xb2, 0x00, /* V-scaling incr chroma low */
+ 0xb3, 0x04, /* " hi */
+ 0xb4, 0x01, /* V-scaling mode control */
+ 0xb8, 0x00, /* V-phase offset chroma 00 */
+ 0xb9, 0x00, /* V-phase offset chroma 01 */
+ 0xba, 0x00, /* V-phase offset chroma 10 */
+ 0xbb, 0x00, /* V-phase offset chroma 11 */
+ 0xbc, 0x00, /* V-phase offset luma 00 */
+ 0xbd, 0x00, /* V-phase offset luma 01 */
+ 0xbe, 0x00, /* V-phase offset luma 10 */
+ 0xbf, 0x00, /* V-phase offset luma 11 */
+
+ /* Task B */
+ 0xd0, 0x01, /* down scale = 1 */
+ 0xd1, 0x00, /* prescale accumulation length = 1 */
+ 0xd2, 0x00, /* dc gain and fir prefilter control */
+ 0xd4, 0x80, /* Lum Brightness, nominal value = 0x80 */
+ 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */
+ 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */
+ 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */
+ 0xd9, 0x04,
+ 0xda, 0x00, /* H-phase offset Luma = 0 */
+ 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
+ 0xdd, 0x02, /* H-scaling incr chroma */
+ 0xde, 0x00, /* H-phase offset chroma. must be offset luma / 2 */
+
+ 0xe0, 0x00, /* V-scaling incr luma low */
+ 0xe1, 0x04, /* " hi */
+ 0xe2, 0x00, /* V-scaling incr chroma low */
+ 0xe3, 0x04, /* " hi */
+ 0xe4, 0x01, /* V-scaling mode control */
+ 0xe8, 0x00, /* V-phase offset chroma 00 */
+ 0xe9, 0x00, /* V-phase offset chroma 01 */
+ 0xea, 0x00, /* V-phase offset chroma 10 */
+ 0xeb, 0x00, /* V-phase offset chroma 11 */
+ 0xec, 0x00, /* V-phase offset luma 00 */
+ 0xed, 0x00, /* V-phase offset luma 01 */
+ 0xee, 0x00, /* V-phase offset luma 10 */
+ 0xef, 0x00, /* V-phase offset luma 11 */
+
+ 0xf2, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
+ 0xf3, 0x46,
+ 0xf4, 0x00,
+ 0xf7, 0x4b, /* not the recommended settings! */
+ 0xf8, 0x00,
+ 0xf9, 0x4b,
+ 0xfa, 0x00,
+ 0xfb, 0x4b,
+ 0xff, 0x88, /* PLL2 lock detection settings: 71 lines 50% phase error */
+
+ /* Turn off VBI */
+ 0x40, 0x20, /* No framing code errors allowed. */
+ 0x41, 0xff,
+ 0x42, 0xff,
+ 0x43, 0xff,
+ 0x44, 0xff,
+ 0x45, 0xff,
+ 0x46, 0xff,
+ 0x47, 0xff,
+ 0x48, 0xff,
+ 0x49, 0xff,
+ 0x4a, 0xff,
+ 0x4b, 0xff,
+ 0x4c, 0xff,
+ 0x4d, 0xff,
+ 0x4e, 0xff,
+ 0x4f, 0xff,
+ 0x50, 0xff,
+ 0x51, 0xff,
+ 0x52, 0xff,
+ 0x53, 0xff,
+ 0x54, 0xff,
+ 0x55, 0xff,
+ 0x56, 0xff,
+ 0x57, 0xff,
+ 0x58, 0x40,
+ 0x59, 0x47,
+ 0x5b, 0x83,
+ 0x5d, 0xbd,
+ 0x5e, 0x35,
+
+ 0x02, 0x84, /* input tuner -> input 4, amplifier active */
+ 0x09, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
+
+ 0x80, 0x20, /* enable task B */
+ 0x88, 0xd0,
+ 0x88, 0xf0,
+ 0x00, 0x00
+};
+
+/* ============== SAA7715 AUDIO settings ============= */
+
+/* 48.0 kHz */
+static const unsigned char saa7115_cfg_48_audio[] = {
+ 0x34, 0xce,
+ 0x35, 0xfb,
+ 0x36, 0x30,
+ 0x00, 0x00
+};
+
+/* 44.1 kHz */
+static const unsigned char saa7115_cfg_441_audio[] = {
+ 0x34, 0xf2,
+ 0x35, 0x00,
+ 0x36, 0x2d,
+ 0x00, 0x00
+};
+
+/* 32.0 kHz */
+static const unsigned char saa7115_cfg_32_audio[] = {
+ 0x34, 0xdf,
+ 0x35, 0xa7,
+ 0x36, 0x20,
+ 0x00, 0x00
+};
+
+/* 48.0 kHz 60hz */
+static const unsigned char saa7115_cfg_60hz_48_audio[] = {
+ 0x30, 0xcd,
+ 0x31, 0x20,
+ 0x32, 0x03,
+ 0x00, 0x00
+};
+
+/* 48.0 kHz 50hz */
+static const unsigned char saa7115_cfg_50hz_48_audio[] = {
+ 0x30, 0x00,
+ 0x31, 0xc0,
+ 0x32, 0x03,
+ 0x00, 0x00
+};
+
+/* 44.1 kHz 60hz */
+static const unsigned char saa7115_cfg_60hz_441_audio[] = {
+ 0x30, 0xbc,
+ 0x31, 0xdf,
+ 0x32, 0x02,
+ 0x00, 0x00
+};
+
+/* 44.1 kHz 50hz */
+static const unsigned char saa7115_cfg_50hz_441_audio[] = {
+ 0x30, 0x00,
+ 0x31, 0x72,
+ 0x32, 0x03,
+ 0x00, 0x00
+};
+
+/* 32.0 kHz 60hz */
+static const unsigned char saa7115_cfg_60hz_32_audio[] = {
+ 0x30, 0xde,
+ 0x31, 0x15,
+ 0x32, 0x02,
+ 0x00, 0x00
+};
+
+/* 32.0 kHz 50hz */
+static const unsigned char saa7115_cfg_50hz_32_audio[] = {
+ 0x30, 0x00,
+ 0x31, 0x80,
+ 0x32, 0x02,
+ 0x00, 0x00
+};
+
+static int saa7115_odd_parity(u8 c)
+{
+ c ^= (c >> 4);
+ c ^= (c >> 2);
+ c ^= (c >> 1);
+
+ return c & 1;
+}
+
+static int saa7115_decode_vps(u8 * dst, u8 * p)
+{
+ static const u8 biphase_tbl[] = {
+ 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+ 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+ 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
+ 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
+ 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
+ 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
+ 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+ 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+ 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
+ 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
+ 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
+ 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
+ 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
+ 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
+ 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
+ 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
+ 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
+ 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
+ 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
+ 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
+ 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
+ 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
+ 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
+ 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
+ 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+ 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+ 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
+ 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
+ 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
+ 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
+ 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+ 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+ };
+ int i;
+ u8 c, err = 0;
+
+ for (i = 0; i < 2 * 13; i += 2) {
+ err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
+ c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
+ dst[i / 2] = c;
+ }
+ return err & 0xf0;
+}
+
+static int saa7115_decode_wss(u8 * p)
+{
+ static const int wss_bits[8] = {
+ 0, 0, 0, 1, 0, 1, 1, 1
+ };
+ unsigned char parity;
+ int wss = 0;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ int b1 = wss_bits[p[i] & 7];
+ int b2 = wss_bits[(p[i] >> 3) & 7];
+
+ if (b1 == b2)
+ return -1;
+ wss |= b2 << i;
+ }
+ parity = wss & 15;
+ parity ^= parity >> 2;
+ parity ^= parity >> 1;
+
+ if (!(parity & 1))
+ return -1;
+
+ return wss;
+}
+
+
+static int saa7115_set_audio_clock_freq(struct i2c_client *client, enum v4l2_audio_clock_freq freq)
+{
+ struct saa7115_state *state = i2c_get_clientdata(client);
+
+ saa7115_dbg("set audio clock freq: %d\n", freq);
+ switch (freq) {
+ case V4L2_AUDCLK_32_KHZ:
+ saa7115_writeregs(client, saa7115_cfg_32_audio);
+ if (state->std & V4L2_STD_525_60) {
+ saa7115_writeregs(client, saa7115_cfg_60hz_32_audio);
+ } else {
+ saa7115_writeregs(client, saa7115_cfg_50hz_32_audio);
+ }
+ break;
+ case V4L2_AUDCLK_441_KHZ:
+ saa7115_writeregs(client, saa7115_cfg_441_audio);
+ if (state->std & V4L2_STD_525_60) {
+ saa7115_writeregs(client, saa7115_cfg_60hz_441_audio);
+ } else {
+ saa7115_writeregs(client, saa7115_cfg_50hz_441_audio);
+ }
+ break;
+ case V4L2_AUDCLK_48_KHZ:
+ saa7115_writeregs(client, saa7115_cfg_48_audio);
+ if (state->std & V4L2_STD_525_60) {
+ saa7115_writeregs(client, saa7115_cfg_60hz_48_audio);
+ } else {
+ saa7115_writeregs(client, saa7115_cfg_50hz_48_audio);
+ }
+ break;
+ default:
+ saa7115_dbg("invalid audio setting %d\n", freq);
+ return -EINVAL;
+ }
+ state->audclk_freq = freq;
+ return 0;
+}
+
+static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+ struct saa7115_state *state = i2c_get_clientdata(client);
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (ctrl->value < 0 || ctrl->value > 255) {
+ saa7115_err("invalid brightness setting %d\n", ctrl->value);
+ return -ERANGE;
+ }
+
+ state->bright = ctrl->value;
+ saa7115_write(client, 0x0a, state->bright);
+ break;
+
+ case V4L2_CID_CONTRAST:
+ if (ctrl->value < 0 || ctrl->value > 127) {
+ saa7115_err("invalid contrast setting %d\n", ctrl->value);
+ return -ERANGE;
+ }
+
+ state->contrast = ctrl->value;
+ saa7115_write(client, 0x0b, state->contrast);
+ break;
+
+ case V4L2_CID_SATURATION:
+ if (ctrl->value < 0 || ctrl->value > 127) {
+ saa7115_err("invalid saturation setting %d\n", ctrl->value);
+ return -ERANGE;
+ }
+
+ state->sat = ctrl->value;
+ saa7115_write(client, 0x0c, state->sat);
+ break;
+
+ case V4L2_CID_HUE:
+ if (ctrl->value < -127 || ctrl->value > 127) {
+ saa7115_err("invalid hue setting %d\n", ctrl->value);
+ return -ERANGE;
+ }
+
+ state->hue = ctrl->value;
+ saa7115_write(client, 0x0d, state->hue);
+ break;
+ }
+
+ return 0;
+}
+
+static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+ struct saa7115_state *state = i2c_get_clientdata(client);
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = state->bright;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = state->contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = state->sat;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = state->hue;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
+{
+ struct saa7115_state *state = i2c_get_clientdata(client);
+ int taskb = saa7115_read(client, 0x80) & 0x10;
+
+ // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
+ if (std & V4L2_STD_525_60) {
+ saa7115_dbg("decoder set standard 60 Hz\n");
+ saa7115_writeregs(client, saa7115_cfg_60hz_video);
+ } else {
+ saa7115_dbg("decoder set standard 50 Hz\n");
+ saa7115_writeregs(client, saa7115_cfg_50hz_video);
+ }
+
+ state->std = std;
+
+ /* restart task B if needed */
+ if (taskb && state->ident == V4L2_IDENT_SAA7114) {
+ saa7115_writeregs(client, saa7115_cfg_vbi_on);
+ }
+
+ /* switch audio mode too! */
+ saa7115_set_audio_clock_freq(client, state->audclk_freq);
+}
+
+static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client)
+{
+ struct saa7115_state *state = i2c_get_clientdata(client);
+
+ return state->std;
+}
+
+static void saa7115_log_status(struct i2c_client *client)
+{
+ static const char * const audclk_freq_strs[] = {
+ "44.1 kHz",
+ "48 kHz",
+ "32 kHz"
+ };
+ struct saa7115_state *state = i2c_get_clientdata(client);
+ int reg1e, reg1f;
+ int signalOk;
+ int vcr;
+
+ saa7115_info("Audio frequency: %s\n", audclk_freq_strs[state->audclk_freq]);
+ if (client->name[6] == '4') {
+ /* status for the saa7114 */
+ reg1f = saa7115_read(client, 0x1f);
+ signalOk = (reg1f & 0xc1) == 0x81;
+ saa7115_info("Video signal: %s\n", signalOk ? "ok" : "bad");
+ saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz");
+ return;
+ }
+
+ /* status for the saa7115 */
+ reg1e = saa7115_read(client, 0x1e);
+ reg1f = saa7115_read(client, 0x1f);
+
+ signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
+ vcr = !(reg1f & 0x10);
+
+ saa7115_info("Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
+ saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz");
+
+ switch (reg1e & 0x03) {
+ case 1:
+ saa7115_info("Detected format: NTSC\n");
+ break;
+ case 2:
+ saa7115_info("Detected format: PAL\n");
+ break;
+ case 3:
+ saa7115_info("Detected format: SECAM\n");
+ break;
+ default:
+ saa7115_info("Detected format: BW/No color\n");
+ break;
+ }
+}
+
+/* setup the sliced VBI lcr registers according to the sliced VBI format */
+static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
+{
+ struct saa7115_state *state = i2c_get_clientdata(client);
+ int is_50hz = (state->std & V4L2_STD_625_50);
+ u8 lcr[24];
+ int i, x;
+
+ /* saa7114 doesn't yet support VBI */
+ if (state->ident == V4L2_IDENT_SAA7114)
+ return;
+
+ for (i = 0; i <= 23; i++)
+ lcr[i] = 0xff;
+
+ if (fmt->service_set == 0) {
+ /* raw VBI */
+ if (is_50hz)
+ for (i = 6; i <= 23; i++)
+ lcr[i] = 0xdd;
+ else
+ for (i = 10; i <= 21; i++)
+ lcr[i] = 0xdd;
+ } else {
+ /* sliced VBI */
+ /* first clear lines that cannot be captured */
+ if (is_50hz) {
+ for (i = 0; i <= 5; i++)
+ fmt->service_lines[0][i] =
+ fmt->service_lines[1][i] = 0;
+ }
+ else {
+ for (i = 0; i <= 9; i++)
+ fmt->service_lines[0][i] =
+ fmt->service_lines[1][i] = 0;
+ for (i = 22; i <= 23; i++)
+ fmt->service_lines[0][i] =
+ fmt->service_lines[1][i] = 0;
+ }
+
+ /* Now set the lcr values according to the specified service */
+ for (i = 6; i <= 23; i++) {
+ lcr[i] = 0;
+ for (x = 0; x <= 1; x++) {
+ switch (fmt->service_lines[1-x][i]) {
+ case 0:
+ lcr[i] |= 0xf << (4 * x);
+ break;
+ case V4L2_SLICED_TELETEXT_B:
+ lcr[i] |= 1 << (4 * x);
+ break;
+ case V4L2_SLICED_CAPTION_525:
+ lcr[i] |= 4 << (4 * x);
+ break;
+ case V4L2_SLICED_WSS_625:
+ lcr[i] |= 5 << (4 * x);
+ break;
+ case V4L2_SLICED_VPS:
+ lcr[i] |= 7 << (4 * x);
+ break;
+ }
+ }
+ }
+ }
+
+ /* write the lcr registers */
+ for (i = 2; i <= 23; i++) {
+ saa7115_write(client, i - 2 + 0x41, lcr[i]);
+ }
+
+ /* enable/disable raw VBI capturing */
+ saa7115_writeregs(client, fmt->service_set == 0 ? saa7115_cfg_vbi_on : saa7115_cfg_vbi_off);
+}
+
+static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+{
+ static u16 lcr2vbi[] = {
+ 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
+ 0, V4L2_SLICED_CAPTION_525, /* 4 */
+ V4L2_SLICED_WSS_625, 0, /* 5 */
+ V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */
+ 0, 0, 0, 0
+ };
+ struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced;
+ int i;
+
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+ memset(sliced, 0, sizeof(*sliced));
+ /* done if using raw VBI */
+ if (saa7115_read(client, 0x80) & 0x10)
+ return 0;
+ for (i = 2; i <= 23; i++) {
+ u8 v = saa7115_read(client, i - 2 + 0x41);
+
+ sliced->service_lines[0][i] = lcr2vbi[v >> 4];
+ sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
+ sliced->service_set |=
+ sliced->service_lines[0][i] | sliced->service_lines[1][i];
+ }
+ return 0;
+}
+
+static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+{
+ struct saa7115_state *state = i2c_get_clientdata(client);
+ struct v4l2_pix_format *pix;
+ int HPSC, HFSC;
+ int VSCY, Vsrc;
+ int is_50hz = state->std & V4L2_STD_625_50;
+
+ if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
+ saa7115_set_lcr(client, &fmt->fmt.sliced);
+ return 0;
+ }
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ pix = &(fmt->fmt.pix);
+
+ saa7115_dbg("decoder set size\n");
+
+ /* FIXME need better bounds checking here */
+ if ((pix->width < 1) || (pix->width > 1440))
+ return -EINVAL;
+ if ((pix->height < 1) || (pix->height > 960))
+ return -EINVAL;
+
+ /* probably have a valid size, let's set it */
+ /* Set output width/height */
+ /* width */
+ saa7115_write(client, 0xcc, (u8) (pix->width & 0xff));
+ saa7115_write(client, 0xcd, (u8) ((pix->width >> 8) & 0xff));
+ /* height */
+ saa7115_write(client, 0xce, (u8) (pix->height & 0xff));
+ saa7115_write(client, 0xcf, (u8) ((pix->height >> 8) & 0xff));
+
+ /* Scaling settings */
+ /* Hprescaler is floor(inres/outres) */
+ /* FIXME hardcoding input res */
+ if (pix->width != 720) {
+ HPSC = (int)(720 / pix->width);
+ /* 0 is not allowed (div. by zero) */
+ HPSC = HPSC ? HPSC : 1;
+ HFSC = (int)((1024 * 720) / (HPSC * pix->width));
+
+ saa7115_dbg("Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
+ /* FIXME hardcodes to "Task B"
+ * write H prescaler integer */
+ saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f));
+
+ /* write H fine-scaling (luminance) */
+ saa7115_write(client, 0xd8, (u8) (HFSC & 0xff));
+ saa7115_write(client, 0xd9, (u8) ((HFSC >> 8) & 0xff));
+ /* write H fine-scaling (chrominance)
+ * must be lum/2, so i'll just bitshift :) */
+ saa7115_write(client, 0xDC, (u8) ((HFSC >> 1) & 0xff));
+ saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff));
+ } else {
+ if (is_50hz) {
+ saa7115_dbg("Setting full 50hz width\n");
+ saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x);
+ } else {
+ saa7115_dbg("Setting full 60hz width\n");
+ saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
+ }
+ }
+
+ Vsrc = is_50hz ? 576 : 480;
+
+ if (pix->height != Vsrc) {
+ VSCY = (int)((1024 * Vsrc) / pix->height);
+ saa7115_dbg("Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
+
+ /* Correct Contrast and Luminance */
+ saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY));
+ saa7115_write(client, 0xd6, (u8) (64 * 1024 / VSCY));
+
+ /* write V fine-scaling (luminance) */
+ saa7115_write(client, 0xe0, (u8) (VSCY & 0xff));
+ saa7115_write(client, 0xe1, (u8) ((VSCY >> 8) & 0xff));
+ /* write V fine-scaling (chrominance) */
+ saa7115_write(client, 0xe2, (u8) (VSCY & 0xff));
+ saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff));
+ } else {
+ if (is_50hz) {
+ saa7115_dbg("Setting full 50Hz height\n");
+ saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y);
+ } else {
+ saa7115_dbg("Setting full 60hz height\n");
+ saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
+ }
+ }
+
+ saa7115_writeregs(client, saa7115_cfg_reset_scaler);
+ return 0;
+}
+
+/* Decode the sliced VBI data stream as created by the saa7115.
+ The format is described in the saa7115 datasheet in Tables 25 and 26
+ and in Figure 33.
+ The current implementation uses SAV/EAV codes and not the ancillary data
+ headers. The vbi->p pointer points to the SDID byte right after the SAV
+ code. */
+static void saa7115_decode_vbi_line(struct i2c_client *client,
+ struct v4l2_decode_vbi_line *vbi)
+{
+ static const char vbi_no_data_pattern[] = {
+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
+ };
+ struct saa7115_state *state = i2c_get_clientdata(client);
+ u8 *p = vbi->p;
+ u32 wss;
+ int id1, id2; /* the ID1 and ID2 bytes from the internal header */
+
+ vbi->type = 0; /* mark result as a failure */
+ id1 = p[2];
+ id2 = p[3];
+ /* Note: the field bit is inverted for 60 Hz video */
+ if (state->std & V4L2_STD_525_60)
+ id1 ^= 0x40;
+
+ /* Skip internal header, p now points to the start of the payload */
+ p += 4;
+ vbi->p = p;
+
+ /* calculate field and line number of the VBI packet (1-23) */
+ vbi->is_second_field = ((id1 & 0x40) != 0);
+ vbi->line = (id1 & 0x3f) << 3;
+ vbi->line |= (id2 & 0x70) >> 4;
+
+ /* Obtain data type */
+ id2 &= 0xf;
+
+ /* If the VBI slicer does not detect any signal it will fill up
+ the payload buffer with 0xa0 bytes. */
+ if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
+ return;
+
+ /* decode payloads */
+ switch (id2) {
+ case 1:
+ vbi->type = V4L2_SLICED_TELETEXT_B;
+ break;
+ case 4:
+ if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1]))
+ return;
+ vbi->type = V4L2_SLICED_CAPTION_525;
+ break;
+ case 5:
+ wss = saa7115_decode_wss(p);
+ if (wss == -1)
+ return;
+ p[0] = wss & 0xff;
+ p[1] = wss >> 8;
+ vbi->type = V4L2_SLICED_WSS_625;
+ break;
+ case 7:
+ if (saa7115_decode_vps(p, p) != 0)
+ return;
+ vbi->type = V4L2_SLICED_VPS;
+ break;
+ default:
+ return;
+ }
+}
+
+/* ============ SAA7115 AUDIO settings (end) ============= */
+
+static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+ struct saa7115_state *state = i2c_get_clientdata(client);
+ int *iarg = arg;
+
+ /* ioctls to allow direct access to the saa7115 registers for testing */
+ switch (cmd) {
+ case VIDIOC_S_FMT:
+ return saa7115_set_v4lfmt(client, (struct v4l2_format *)arg);
+
+ case VIDIOC_G_FMT:
+ return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg);
+
+ case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+ return saa7115_set_audio_clock_freq(client, *(enum v4l2_audio_clock_freq *)arg);
+
+ case VIDIOC_G_TUNER:
+ {
+ struct v4l2_tuner *vt = arg;
+ int status;
+
+ status = saa7115_read(client, 0x1f);
+
+ saa7115_dbg("status: 0x%02x\n", status);
+ vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
+ break;
+ }
+
+ case VIDIOC_LOG_STATUS:
+ saa7115_log_status(client);
+ break;
+
+ case VIDIOC_G_CTRL:
+ return saa7115_get_v4lctrl(client, (struct v4l2_control *)arg);
+
+ case VIDIOC_S_CTRL:
+ return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg);
+
+ case VIDIOC_G_STD:
+ *(v4l2_std_id *)arg = saa7115_get_v4lstd(client);
+ break;
+
+ case VIDIOC_S_STD:
+ saa7115_set_v4lstd(client, *(v4l2_std_id *)arg);
+ break;
+
+ case VIDIOC_G_INPUT:
+ *(int *)arg = state->input;
+ break;
+
+ case VIDIOC_S_INPUT:
+ saa7115_dbg("decoder set input %d\n", *iarg);
+ /* inputs from 0-9 are available */
+ if (*iarg < 0 || *iarg > 9) {
+ return -EINVAL;
+ }
+
+ if (state->input == *iarg)
+ break;
+ saa7115_dbg("now setting %s input\n",
+ *iarg >= 6 ? "S-Video" : "Composite");
+ state->input = *iarg;
+
+ /* select mode */
+ saa7115_write(client, 0x02,
+ (saa7115_read(client, 0x02) & 0xf0) |
+ state->input);
+
+ /* bypass chrominance trap for modes 6..9 */
+ saa7115_write(client, 0x09,
+ (saa7115_read(client, 0x09) & 0x7f) |
+ (state->input < 6 ? 0x0 : 0x80));
+ break;
+
+ case VIDIOC_STREAMON:
+ case VIDIOC_STREAMOFF:
+ saa7115_dbg("%s output\n",
+ (cmd == VIDIOC_STREAMON) ? "enable" : "disable");
+
+ if (state->enable != (cmd == VIDIOC_STREAMON)) {
+ state->enable = (cmd == VIDIOC_STREAMON);
+ saa7115_write(client, 0x87, state->enable);
+ }
+ break;
+
+ case VIDIOC_INT_DECODE_VBI_LINE:
+ saa7115_decode_vbi_line(client, arg);
+ break;
+
+ case VIDIOC_INT_RESET:
+ saa7115_dbg("decoder RESET\n");
+ saa7115_writeregs(client, saa7115_cfg_reset_scaler);
+ break;
+
+ case VIDIOC_INT_G_VBI_DATA:
+ {
+ struct v4l2_sliced_vbi_data *data = arg;
+
+ switch (data->id) {
+ case V4L2_SLICED_WSS_625:
+ if (saa7115_read(client, 0x6b) & 0xc0)
+ return -EIO;
+ data->data[0] = saa7115_read(client, 0x6c);
+ data->data[1] = saa7115_read(client, 0x6d);
+ return 0;
+ case V4L2_SLICED_CAPTION_525:
+ if (data->field == 0) {
+ /* CC */
+ if (saa7115_read(client, 0x66) & 0xc0)
+ return -EIO;
+ data->data[0] = saa7115_read(client, 0x67);
+ data->data[1] = saa7115_read(client, 0x68);
+ return 0;
+ }
+ /* XDS */
+ if (saa7115_read(client, 0x66) & 0x30)
+ return -EIO;
+ data->data[0] = saa7115_read(client, 0x69);
+ data->data[1] = saa7115_read(client, 0x6a);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+ break;
+ }
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ case VIDIOC_INT_G_REGISTER:
+ {
+ struct v4l2_register *reg = arg;
+
+ if (reg->i2c_id != I2C_DRIVERID_SAA711X)
+ return -EINVAL;
+ reg->val = saa7115_read(client, reg->reg & 0xff);
+ break;
+ }
+
+ case VIDIOC_INT_S_REGISTER:
+ {
+ struct v4l2_register *reg = arg;
+
+ if (reg->i2c_id != I2C_DRIVERID_SAA711X)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ saa7115_write(client, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ }
+#endif
+
+ case VIDIOC_INT_G_CHIP_IDENT:
+ *iarg = state->ident;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_driver i2c_driver_saa7115;
+
+static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *client;
+ struct saa7115_state *state;
+ u8 chip_id;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == 0)
+ return -ENOMEM;
+ memset(client, 0, sizeof(struct i2c_client));
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &i2c_driver_saa7115;
+ client->flags = I2C_CLIENT_ALLOW_USE;
+ snprintf(client->name, sizeof(client->name) - 1, "saa7115");
+
+ saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1);
+
+ saa7115_write(client, 0, 5);
+ chip_id = saa7115_read(client, 0) & 0x0f;
+ if (chip_id != 4 && chip_id != 5) {
+ saa7115_dbg("saa7115 not found\n");
+ kfree(client);
+ return 0;
+ }
+ if (chip_id == 4) {
+ snprintf(client->name, sizeof(client->name) - 1, "saa7114");
+ }
+ saa7115_info("saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name);
+
+ state = kmalloc(sizeof(struct saa7115_state), GFP_KERNEL);
+ i2c_set_clientdata(client, state);
+ if (state == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ memset(state, 0, sizeof(struct saa7115_state));
+ state->std = V4L2_STD_NTSC;
+ state->input = -1;
+ state->enable = 1;
+ state->bright = 128;
+ state->contrast = 64;
+ state->hue = 0;
+ state->sat = 64;
+ state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115;
+ state->audclk_freq = V4L2_AUDCLK_48_KHZ;
+
+ saa7115_dbg("writing init values\n");
+
+ /* init to 60hz/48khz */
+ saa7115_writeregs(client, saa7115_init_auto_input);
+ saa7115_writeregs(client, saa7115_init_misc);
+ saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
+ saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
+ saa7115_writeregs(client, saa7115_cfg_60hz_video);
+ saa7115_writeregs(client, saa7115_cfg_48_audio);
+ saa7115_writeregs(client, saa7115_cfg_60hz_48_audio);
+ saa7115_writeregs(client, saa7115_cfg_reset_scaler);
+
+ i2c_attach_client(client);
+
+ saa7115_dbg("status: (1E) 0x%02x, (1F) 0x%02x\n",
+ saa7115_read(client, 0x1e), saa7115_read(client, 0x1f));
+
+ return 0;
+}
+
+static int saa7115_probe(struct i2c_adapter *adapter)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+ if (adapter->class & I2C_CLASS_TV_ANALOG)
+#else
+ if (adapter->id == I2C_HW_B_BT848)
+#endif
+ return i2c_probe(adapter, &addr_data, &saa7115_attach);
+ return 0;
+}
+
+static int saa7115_detach(struct i2c_client *client)
+{
+ struct saa7115_state *state = i2c_get_clientdata(client);
+ int err;
+
+ err = i2c_detach_client(client);
+ if (err) {
+ return err;
+ }
+
+ kfree(state);
+ kfree(client);
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+static struct i2c_driver i2c_driver_saa7115 = {
+ .name = "saa7115",
+ .id = I2C_DRIVERID_SAA711X,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = saa7115_probe,
+ .detach_client = saa7115_detach,
+ .command = saa7115_command,
+ .owner = THIS_MODULE,
+};
+
+
+static int __init saa7115_init_module(void)
+{
+ return i2c_add_driver(&i2c_driver_saa7115);
+}
+
+static void __exit saa7115_cleanup_module(void)
+{
+ i2c_del_driver(&i2c_driver_saa7115);
+}
+
+module_init(saa7115_init_module);
+module_exit(saa7115_cleanup_module);
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c
index 9aa8827..25b30f3 100644
--- a/drivers/media/video/saa711x.c
+++ b/drivers/media/video/saa711x.c
@@ -36,7 +36,6 @@
#include <asm/pgtable.h>
#include <asm/page.h>
#include <linux/sched.h>
-#include <asm/segment.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <linux/videodev.h>
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
new file mode 100644
index 0000000..843431f
--- /dev/null
+++ b/drivers/media/video/saa7127.c
@@ -0,0 +1,849 @@
+/*
+ * saa7127 - Philips SAA7127/SAA7129 video encoder driver
+ *
+ * Copyright (C) 2003 Roy Bulter <rbulter@hetnet.nl>
+ *
+ * Based on SAA7126 video encoder driver by Gillem & Andreas Oberritter
+ *
+ * Copyright (C) 2000-2001 Gillem <htoa@gmx.net>
+ * Copyright (C) 2002 Andreas Oberritter <obi@saftware.de>
+ *
+ * Based on Stadis 4:2:2 MPEG-2 Decoder Driver by Nathan Laredo
+ *
+ * Copyright (C) 1999 Nathan Laredo <laredo@gnu.org>
+ *
+ * This driver is designed for the Hauppauge 250/350 Linux driver
+ * from the ivtv Project
+ *
+ * Copyright (C) 2003 Kevin Thayer <nufan_wfk@yahoo.com>
+ *
+ * Dual output support:
+ * Copyright (C) 2004 Eric Varsanyi
+ *
+ * NTSC Tuning and 7.5 IRE Setup
+ * Copyright (C) 2004 Chris Kennedy <c@groovy.org>
+ *
+ * VBI additions & cleanup:
+ * Copyright (C) 2004, 2005 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * Note: the saa7126 is identical to the saa7127, and the saa7128 is
+ * identical to the saa7129, except that the saa7126 and saa7128 have
+ * macrovision anti-taping support. This driver will almost certainly
+ * work find for those chips, except of course for the missing anti-taping
+ * support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+
+static int debug = 0;
+static int test_image = 0;
+
+MODULE_DESCRIPTION("Philips SAA7127/9 video encoder driver");
+MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
+MODULE_LICENSE("GPL");
+module_param(debug, int, 0644);
+module_param(test_image, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-2)");
+MODULE_PARM_DESC(test_image, "test_image (0-1)");
+
+#define saa7127_dbg(fmt, arg...) \
+ do { \
+ if (debug >= 1) \
+ printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); \
+ } while (0)
+
+/* High volume debug. Use with care. */
+#define saa7127_dbg_highvol(fmt, arg...) \
+ do { \
+ if (debug == 2) \
+ printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); \
+ } while (0)
+
+#define saa7127_err(fmt, arg...) do { \
+ printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+#define saa7127_info(fmt, arg...) do { \
+ printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+
+
+I2C_CLIENT_INSMOD;
+
+/*
+ * SAA7127 registers
+ */
+
+#define SAA7127_REG_STATUS 0x00
+#define SAA7127_REG_WIDESCREEN_CONFIG 0x26
+#define SAA7127_REG_WIDESCREEN_ENABLE 0x27
+#define SAA7127_REG_BURST_START 0x28
+#define SAA7127_REG_BURST_END 0x29
+#define SAA7127_REG_COPYGEN_0 0x2a
+#define SAA7127_REG_COPYGEN_1 0x2b
+#define SAA7127_REG_COPYGEN_2 0x2c
+#define SAA7127_REG_OUTPUT_PORT_CONTROL 0x2d
+#define SAA7127_REG_GAIN_LUMINANCE_RGB 0x38
+#define SAA7127_REG_GAIN_COLORDIFF_RGB 0x39
+#define SAA7127_REG_INPUT_PORT_CONTROL_1 0x3a
+#define SAA7129_REG_FADE_KEY_COL2 0x4f
+#define SAA7127_REG_CHROMA_PHASE 0x5a
+#define SAA7127_REG_GAINU 0x5b
+#define SAA7127_REG_GAINV 0x5c
+#define SAA7127_REG_BLACK_LEVEL 0x5d
+#define SAA7127_REG_BLANKING_LEVEL 0x5e
+#define SAA7127_REG_VBI_BLANKING 0x5f
+#define SAA7127_REG_DAC_CONTROL 0x61
+#define SAA7127_REG_BURST_AMP 0x62
+#define SAA7127_REG_SUBC3 0x63
+#define SAA7127_REG_SUBC2 0x64
+#define SAA7127_REG_SUBC1 0x65
+#define SAA7127_REG_SUBC0 0x66
+#define SAA7127_REG_LINE_21_ODD_0 0x67
+#define SAA7127_REG_LINE_21_ODD_1 0x68
+#define SAA7127_REG_LINE_21_EVEN_0 0x69
+#define SAA7127_REG_LINE_21_EVEN_1 0x6a
+#define SAA7127_REG_RCV_PORT_CONTROL 0x6b
+#define SAA7127_REG_VTRIG 0x6c
+#define SAA7127_REG_HTRIG_HI 0x6d
+#define SAA7127_REG_MULTI 0x6e
+#define SAA7127_REG_CLOSED_CAPTION 0x6f
+#define SAA7127_REG_RCV2_OUTPUT_START 0x70
+#define SAA7127_REG_RCV2_OUTPUT_END 0x71
+#define SAA7127_REG_RCV2_OUTPUT_MSBS 0x72
+#define SAA7127_REG_TTX_REQUEST_H_START 0x73
+#define SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH 0x74
+#define SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT 0x75
+#define SAA7127_REG_TTX_ODD_REQ_VERT_START 0x76
+#define SAA7127_REG_TTX_ODD_REQ_VERT_END 0x77
+#define SAA7127_REG_TTX_EVEN_REQ_VERT_START 0x78
+#define SAA7127_REG_TTX_EVEN_REQ_VERT_END 0x79
+#define SAA7127_REG_FIRST_ACTIVE 0x7a
+#define SAA7127_REG_LAST_ACTIVE 0x7b
+#define SAA7127_REG_MSB_VERTICAL 0x7c
+#define SAA7127_REG_DISABLE_TTX_LINE_LO_0 0x7e
+#define SAA7127_REG_DISABLE_TTX_LINE_LO_1 0x7f
+
+/*
+ **********************************************************************
+ *
+ * Arrays with configuration parameters for the SAA7127
+ *
+ **********************************************************************
+ */
+
+struct i2c_reg_value {
+ unsigned char reg;
+ unsigned char value;
+};
+
+static const struct i2c_reg_value saa7129_init_config_extra[] = {
+ { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 },
+ { SAA7127_REG_VTRIG, 0xfa },
+};
+
+static const struct i2c_reg_value saa7127_init_config_common[] = {
+ { SAA7127_REG_WIDESCREEN_CONFIG, 0x0d },
+ { SAA7127_REG_WIDESCREEN_ENABLE, 0x00 },
+ { SAA7127_REG_COPYGEN_0, 0x77 },
+ { SAA7127_REG_COPYGEN_1, 0x41 },
+ { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */
+ { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x9e },
+ { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 },
+ { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 },
+ { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */
+ { SAA7127_REG_LINE_21_ODD_0, 0x77 },
+ { SAA7127_REG_LINE_21_ODD_1, 0x41 },
+ { SAA7127_REG_LINE_21_EVEN_0, 0x88 },
+ { SAA7127_REG_LINE_21_EVEN_1, 0x41 },
+ { SAA7127_REG_RCV_PORT_CONTROL, 0x12 },
+ { SAA7127_REG_VTRIG, 0xf9 },
+ { SAA7127_REG_HTRIG_HI, 0x00 },
+ { SAA7127_REG_RCV2_OUTPUT_START, 0x41 },
+ { SAA7127_REG_RCV2_OUTPUT_END, 0xc3 },
+ { SAA7127_REG_RCV2_OUTPUT_MSBS, 0x00 },
+ { SAA7127_REG_TTX_REQUEST_H_START, 0x3e },
+ { SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH, 0xb8 },
+ { SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT, 0x03 },
+ { SAA7127_REG_TTX_ODD_REQ_VERT_START, 0x15 },
+ { SAA7127_REG_TTX_ODD_REQ_VERT_END, 0x16 },
+ { SAA7127_REG_TTX_EVEN_REQ_VERT_START, 0x15 },
+ { SAA7127_REG_TTX_EVEN_REQ_VERT_END, 0x16 },
+ { SAA7127_REG_FIRST_ACTIVE, 0x1a },
+ { SAA7127_REG_LAST_ACTIVE, 0x01 },
+ { SAA7127_REG_MSB_VERTICAL, 0xc0 },
+ { SAA7127_REG_DISABLE_TTX_LINE_LO_0, 0x00 },
+ { SAA7127_REG_DISABLE_TTX_LINE_LO_1, 0x00 },
+ { 0, 0 }
+};
+
+#define SAA7127_60HZ_DAC_CONTROL 0x15
+static const struct i2c_reg_value saa7127_init_config_60hz[] = {
+ { SAA7127_REG_BURST_START, 0x19 },
+ /* BURST_END is also used as a chip ID in saa7127_detect_client */
+ { SAA7127_REG_BURST_END, 0x1d },
+ { SAA7127_REG_CHROMA_PHASE, 0xa3 },
+ { SAA7127_REG_GAINU, 0x98 },
+ { SAA7127_REG_GAINV, 0xd3 },
+ { SAA7127_REG_BLACK_LEVEL, 0x39 },
+ { SAA7127_REG_BLANKING_LEVEL, 0x2e },
+ { SAA7127_REG_VBI_BLANKING, 0x2e },
+ { SAA7127_REG_DAC_CONTROL, 0x15 },
+ { SAA7127_REG_BURST_AMP, 0x4d },
+ { SAA7127_REG_SUBC3, 0x1f },
+ { SAA7127_REG_SUBC2, 0x7c },
+ { SAA7127_REG_SUBC1, 0xf0 },
+ { SAA7127_REG_SUBC0, 0x21 },
+ { SAA7127_REG_MULTI, 0x90 },
+ { SAA7127_REG_CLOSED_CAPTION, 0x11 },
+ { 0, 0 }
+};
+
+#define SAA7127_50HZ_DAC_CONTROL 0x02
+struct i2c_reg_value saa7127_init_config_50hz[] = {
+ { SAA7127_REG_BURST_START, 0x21 },
+ /* BURST_END is also used as a chip ID in saa7127_detect_client */
+ { SAA7127_REG_BURST_END, 0x1d },
+ { SAA7127_REG_CHROMA_PHASE, 0x3f },
+ { SAA7127_REG_GAINU, 0x7d },
+ { SAA7127_REG_GAINV, 0xaf },
+ { SAA7127_REG_BLACK_LEVEL, 0x33 },
+ { SAA7127_REG_BLANKING_LEVEL, 0x35 },
+ { SAA7127_REG_VBI_BLANKING, 0x35 },
+ { SAA7127_REG_DAC_CONTROL, 0x02 },
+ { SAA7127_REG_BURST_AMP, 0x2f },
+ { SAA7127_REG_SUBC3, 0xcb },
+ { SAA7127_REG_SUBC2, 0x8a },
+ { SAA7127_REG_SUBC1, 0x09 },
+ { SAA7127_REG_SUBC0, 0x2a },
+ { SAA7127_REG_MULTI, 0xa0 },
+ { SAA7127_REG_CLOSED_CAPTION, 0x00 },
+ { 0, 0 }
+};
+
+/* Enumeration for the Supported input types */
+enum saa7127_input_type {
+ SAA7127_INPUT_TYPE_NORMAL,
+ SAA7127_INPUT_TYPE_TEST_IMAGE
+};
+
+/* Enumeration for the Supported Output signal types */
+enum saa7127_output_type {
+ SAA7127_OUTPUT_TYPE_BOTH,
+ SAA7127_OUTPUT_TYPE_COMPOSITE,
+ SAA7127_OUTPUT_TYPE_SVIDEO,
+ SAA7127_OUTPUT_TYPE_RGB,
+ SAA7127_OUTPUT_TYPE_YUV_C,
+ SAA7127_OUTPUT_TYPE_YUV_V
+};
+
+/*
+ **********************************************************************
+ *
+ * Encoder Struct, holds the configuration state of the encoder
+ *
+ **********************************************************************
+ */
+
+struct saa7127_state {
+ v4l2_std_id std;
+ enum v4l2_chip_ident ident;
+ enum saa7127_input_type input_type;
+ enum saa7127_output_type output_type;
+ int video_enable;
+ int wss_enable;
+ u16 wss_mode;
+ int cc_enable;
+ u16 cc_data;
+ int xds_enable;
+ u16 xds_data;
+ int vps_enable;
+ u8 vps_data[5];
+ u8 reg_2d;
+ u8 reg_3a;
+ u8 reg_3a_cb; /* colorbar bit */
+ u8 reg_61;
+};
+
+static const char * const output_strs[] =
+{
+ "S-Video + Composite",
+ "Composite",
+ "S-Video",
+ "RGB",
+ "YUV C",
+ "YUV V"
+};
+
+static const char * const wss_strs[] = {
+ "invalid",
+ "letterbox 14:9 center",
+ "letterbox 14:9 top",
+ "invalid",
+ "letterbox 16:9 top",
+ "invalid",
+ "invalid",
+ "16:9 full format anamorphic"
+ "4:3 full format",
+ "invalid",
+ "invalid",
+ "letterbox 16:9 center",
+ "invalid",
+ "letterbox >16:9 center",
+ "14:9 full format center",
+ "invalid",
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_read(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_write(struct i2c_client *client, u8 reg, u8 val)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ if (i2c_smbus_write_byte_data(client, reg, val) == 0)
+ return 0;
+ }
+ saa7127_err("I2C Write Problem\n");
+ return -1;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_write_inittab(struct i2c_client *client,
+ const struct i2c_reg_value *regs)
+{
+ while (regs->reg != 0) {
+ saa7127_write(client, regs->reg, regs->value);
+ regs++;
+ }
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
+{
+ struct saa7127_state *state = i2c_get_clientdata(client);
+ int enable = (data->line != 0);
+
+ if (enable && (data->field != 0 || data->line != 16))
+ return -EINVAL;
+ if (state->vps_enable != enable) {
+ saa7127_dbg("Turn VPS Signal %s\n", enable ? "on" : "off");
+ saa7127_write(client, 0x54, enable << 7);
+ state->vps_enable = enable;
+ }
+ if (!enable)
+ return 0;
+
+ state->vps_data[0] = data->data[4];
+ state->vps_data[1] = data->data[10];
+ state->vps_data[2] = data->data[11];
+ state->vps_data[3] = data->data[12];
+ state->vps_data[4] = data->data[13];
+ saa7127_dbg("Set VPS data %02x %02x %02x %02x %02x\n",
+ state->vps_data[0], state->vps_data[1],
+ state->vps_data[2], state->vps_data[3],
+ state->vps_data[4]);
+ saa7127_write(client, 0x55, state->vps_data[0]);
+ saa7127_write(client, 0x56, state->vps_data[1]);
+ saa7127_write(client, 0x57, state->vps_data[2]);
+ saa7127_write(client, 0x58, state->vps_data[3]);
+ saa7127_write(client, 0x59, state->vps_data[4]);
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
+{
+ struct saa7127_state *state = i2c_get_clientdata(client);
+ u16 cc = data->data[0] << 8 | data->data[1];
+ int enable = (data->line != 0);
+
+ if (enable && (data->field != 0 || data->line != 21))
+ return -EINVAL;
+ if (state->cc_enable != enable) {
+ saa7127_dbg("Turn CC %s\n", enable ? "on" : "off");
+ saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
+ (enable << 6) | 0x11);
+ state->cc_enable = enable;
+ }
+ if (!enable)
+ return 0;
+
+ saa7127_dbg_highvol("CC data: %04x\n", cc);
+ saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff);
+ saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8);
+ state->cc_data = cc;
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
+{
+ struct saa7127_state *state = i2c_get_clientdata(client);
+ u16 xds = data->data[1] << 8 | data->data[0];
+ int enable = (data->line != 0);
+
+ if (enable && (data->field != 1 || data->line != 21))
+ return -EINVAL;
+ if (state->xds_enable != enable) {
+ saa7127_dbg("Turn XDS %s\n", enable ? "on" : "off");
+ saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
+ (enable << 7) | 0x11);
+ state->xds_enable = enable;
+ }
+ if (!enable)
+ return 0;
+
+ saa7127_dbg_highvol("XDS data: %04x\n", xds);
+ saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff);
+ saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8);
+ state->xds_data = xds;
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
+{
+ struct saa7127_state *state = i2c_get_clientdata(client);
+ int enable = (data->line != 0);
+
+ if (enable && (data->field != 0 || data->line != 23))
+ return -EINVAL;
+ if (state->wss_enable != enable) {
+ saa7127_dbg("Turn WSS %s\n", enable ? "on" : "off");
+ saa7127_write(client, 0x27, enable << 7);
+ state->wss_enable = enable;
+ }
+ if (!enable)
+ return 0;
+
+ saa7127_write(client, 0x26, data->data[0]);
+ saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f));
+ saa7127_dbg("WSS mode: %s\n", wss_strs[data->data[0] & 0xf]);
+ state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0];
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_video_enable(struct i2c_client *client, int enable)
+{
+ struct saa7127_state *state = i2c_get_clientdata(client);
+
+ if (enable) {
+ saa7127_dbg("Enable Video Output\n");
+ saa7127_write(client, 0x2d, state->reg_2d);
+ saa7127_write(client, 0x61, state->reg_61);
+ } else {
+ saa7127_dbg("Disable Video Output\n");
+ saa7127_write(client, 0x2d, (state->reg_2d & 0xf0));
+ saa7127_write(client, 0x61, (state->reg_61 | 0xc0));
+ }
+ state->video_enable = enable;
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std)
+{
+ struct saa7127_state *state = i2c_get_clientdata(client);
+ const struct i2c_reg_value *inittab;
+
+ if (std & V4L2_STD_525_60) {
+ saa7127_dbg("Selecting 60 Hz video Standard\n");
+ inittab = saa7127_init_config_60hz;
+ state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
+ } else {
+ saa7127_dbg("Selecting 50 Hz video Standard\n");
+ inittab = saa7127_init_config_50hz;
+ state->reg_61 = SAA7127_50HZ_DAC_CONTROL;
+ }
+
+ /* Write Table */
+ saa7127_write_inittab(client, inittab);
+ state->std = std;
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_output_type(struct i2c_client *client, int output)
+{
+ struct saa7127_state *state = i2c_get_clientdata(client);
+
+ switch (output) {
+ case SAA7127_OUTPUT_TYPE_RGB:
+ state->reg_2d = 0x0f; /* RGB + CVBS (for sync) */
+ state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
+ break;
+
+ case SAA7127_OUTPUT_TYPE_COMPOSITE:
+ state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
+ state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
+ break;
+
+ case SAA7127_OUTPUT_TYPE_SVIDEO:
+ state->reg_2d = 0xff; /* 11111111 croma -> R, luma -> CVBS + G + B */
+ state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
+ break;
+
+ case SAA7127_OUTPUT_TYPE_YUV_V:
+ state->reg_2d = 0x4f; /* reg 2D = 01001111, all DAC's on, RGB + VBS */
+ state->reg_3a = 0x0b; /* reg 3A = 00001011, bypass RGB-matrix */
+ break;
+
+ case SAA7127_OUTPUT_TYPE_YUV_C:
+ state->reg_2d = 0x0f; /* reg 2D = 00001111, all DAC's on, RGB + CVBS */
+ state->reg_3a = 0x0b; /* reg 3A = 00001011, bypass RGB-matrix */
+ break;
+
+ case SAA7127_OUTPUT_TYPE_BOTH:
+ state->reg_2d = 0xbf;
+ state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ saa7127_dbg("Selecting %s output type\n", output_strs[output]);
+
+ /* Configure Encoder */
+ saa7127_write(client, 0x2d, state->reg_2d);
+ saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
+ state->output_type = output;
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_input_type(struct i2c_client *client, int input)
+{
+ struct saa7127_state *state = i2c_get_clientdata(client);
+
+ switch (input) {
+ case SAA7127_INPUT_TYPE_NORMAL: /* avia */
+ saa7127_dbg("Selecting Normal Encoder Input\n");
+ state->reg_3a_cb = 0;
+ break;
+
+ case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */
+ saa7127_dbg("Selecting Color Bar generator\n");
+ state->reg_3a_cb = 0x80;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
+ state->input_type = input;
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_command(struct i2c_client *client,
+ unsigned int cmd, void *arg)
+{
+ struct saa7127_state *state = i2c_get_clientdata(client);
+ struct v4l2_format *fmt = arg;
+ int *iarg = arg;
+
+ switch (cmd) {
+ case VIDIOC_S_STD:
+ if (state->std == *(v4l2_std_id *)arg)
+ break;
+ return saa7127_set_std(client, *(v4l2_std_id *)arg);
+
+ case VIDIOC_G_STD:
+ *(v4l2_std_id *)arg = state->std;
+ break;
+
+ case VIDIOC_S_INPUT:
+ if (state->input_type == *iarg)
+ break;
+ return saa7127_set_input_type(client, *iarg);
+
+ case VIDIOC_S_OUTPUT:
+ if (state->output_type == *iarg)
+ break;
+ return saa7127_set_output_type(client, *iarg);
+
+ case VIDIOC_STREAMON:
+ case VIDIOC_STREAMOFF:
+ if (state->video_enable == (cmd == VIDIOC_STREAMON))
+ break;
+ return saa7127_set_video_enable(client, cmd == VIDIOC_STREAMON);
+
+ case VIDIOC_G_FMT:
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+
+ memset(&fmt->fmt.sliced, 0, sizeof(fmt->fmt.sliced));
+ if (state->vps_enable)
+ fmt->fmt.sliced.service_lines[0][16] = V4L2_SLICED_VPS;
+ if (state->wss_enable)
+ fmt->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+ if (state->cc_enable) {
+ fmt->fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525;
+ fmt->fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525;
+ }
+ fmt->fmt.sliced.service_set =
+ (state->vps_enable ? V4L2_SLICED_VPS : 0) |
+ (state->wss_enable ? V4L2_SLICED_WSS_625 : 0) |
+ (state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0);
+ break;
+
+ case VIDIOC_LOG_STATUS:
+ saa7127_info("Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz");
+ saa7127_info("Input: %s\n", state->input_type ? "color bars" : "normal");
+ saa7127_info("Output: %s\n", state->video_enable ?
+ output_strs[state->output_type] : "disabled");
+ saa7127_info("WSS: %s\n", state->wss_enable ?
+ wss_strs[state->wss_mode] : "disabled");
+ saa7127_info("VPS: %s\n", state->vps_enable ? "enabled" : "disabled");
+ saa7127_info("CC: %s\n", state->cc_enable ? "enabled" : "disabled");
+ break;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ case VIDIOC_INT_G_REGISTER:
+ {
+ struct v4l2_register *reg = arg;
+
+ if (reg->i2c_id != I2C_DRIVERID_SAA7127)
+ return -EINVAL;
+ reg->val = saa7127_read(client, reg->reg & 0xff);
+ break;
+ }
+
+ case VIDIOC_INT_S_REGISTER:
+ {
+ struct v4l2_register *reg = arg;
+
+ if (reg->i2c_id != I2C_DRIVERID_SAA7127)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ }
+#endif
+
+ case VIDIOC_INT_S_VBI_DATA:
+ {
+ struct v4l2_sliced_vbi_data *data = arg;
+
+ switch (data->id) {
+ case V4L2_SLICED_WSS_625:
+ return saa7127_set_wss(client, data);
+ case V4L2_SLICED_VPS:
+ return saa7127_set_vps(client, data);
+ case V4L2_SLICED_CAPTION_525:
+ if (data->field == 0)
+ return saa7127_set_cc(client, data);
+ return saa7127_set_xds(client, data);
+ default:
+ return -EINVAL;
+ }
+ break;
+ }
+
+ case VIDIOC_INT_G_CHIP_IDENT:
+ *(enum v4l2_chip_ident *)arg = state->ident;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+struct i2c_driver i2c_driver_saa7127;
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *client;
+ struct saa7127_state *state;
+ struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */
+ int read_result = 0;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == 0)
+ return -ENOMEM;
+
+ memset(client, 0, sizeof(struct i2c_client));
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &i2c_driver_saa7127;
+ client->flags = I2C_CLIENT_ALLOW_USE;
+ snprintf(client->name, sizeof(client->name) - 1, "saa7127");
+
+ saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1);
+
+ /* First test register 0: Bits 5-7 are a version ID (should be 0),
+ and bit 2 should also be 0.
+ This is rather general, so the second test is more specific and
+ looks at the 'ending point of burst in clock cycles' which is
+ 0x1d after a reset and not expected to ever change. */
+ if ((saa7127_read(client, 0) & 0xe4) != 0 ||
+ (saa7127_read(client, 0x29) & 0x3f) != 0x1d) {
+ saa7127_dbg("saa7127 not found\n");
+ kfree(client);
+ return 0;
+ }
+ state = kmalloc(sizeof(struct saa7127_state), GFP_KERNEL);
+
+ if (state == NULL) {
+ kfree(client);
+ return (-ENOMEM);
+ }
+
+ i2c_set_clientdata(client, state);
+ memset(state, 0, sizeof(struct saa7127_state));
+
+ /* Configure Encoder */
+
+ saa7127_dbg("Configuring encoder\n");
+ saa7127_write_inittab(client, saa7127_init_config_common);
+ saa7127_set_std(client, V4L2_STD_NTSC);
+ saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH);
+ saa7127_set_vps(client, &vbi);
+ saa7127_set_wss(client, &vbi);
+ saa7127_set_cc(client, &vbi);
+ saa7127_set_xds(client, &vbi);
+ if (test_image == 1) {
+ /* The Encoder has an internal Colorbar generator */
+ /* This can be used for debugging */
+ saa7127_set_input_type(client, SAA7127_INPUT_TYPE_TEST_IMAGE);
+ } else {
+ saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL);
+ }
+ saa7127_set_video_enable(client, 1);
+
+ /* Detect if it's an saa7129 */
+ read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2);
+ saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa);
+ if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
+ saa7127_info("saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name);
+ saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result);
+ saa7127_write_inittab(client, saa7129_init_config_extra);
+ state->ident = V4L2_IDENT_SAA7129;
+ } else {
+ saa7127_info("saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name);
+ state->ident = V4L2_IDENT_SAA7127;
+ }
+
+ i2c_attach_client(client);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_probe(struct i2c_adapter *adapter)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+ if (adapter->class & I2C_CLASS_TV_ANALOG)
+#else
+ if (adapter->id == I2C_HW_B_BT848)
+#endif
+ return i2c_probe(adapter, &addr_data, saa7127_attach);
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_detach(struct i2c_client *client)
+{
+ struct saa7127_state *state = i2c_get_clientdata(client);
+ int err;
+
+ /* Turn off TV output */
+ saa7127_set_video_enable(client, 0);
+
+ err = i2c_detach_client(client);
+
+ if (err) {
+ return err;
+ }
+
+ kfree(state);
+ kfree(client);
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+struct i2c_driver i2c_driver_saa7127 = {
+ .name = "saa7127",
+ .id = I2C_DRIVERID_SAA7127,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = saa7127_probe,
+ .detach_client = saa7127_detach,
+ .command = saa7127_command,
+ .owner = THIS_MODULE,
+};
+
+
+/* ----------------------------------------------------------------------- */
+
+static int __init saa7127_init_module(void)
+{
+ return i2c_add_driver(&i2c_driver_saa7127);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void __exit saa7127_cleanup_module(void)
+{
+ i2c_del_driver(&i2c_driver_saa7127);
+}
+
+/* ----------------------------------------------------------------------- */
+
+module_init(saa7127_init_module);
+module_exit(saa7127_cleanup_module);
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 624e880..7bdeabe 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -1,10 +1,11 @@
config VIDEO_SAA7134
tristate "Philips SAA7134 support"
- depends on VIDEO_DEV && PCI && I2C && SOUND
+ depends on VIDEO_DEV && PCI && I2C && SOUND && SND
select VIDEO_BUF
select VIDEO_IR
select VIDEO_TUNER
select CRC32
+ select SND_PCM_OSS
---help---
This is a video4linux driver for Philips SAA713x based
TV cards.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index e0b28f0..4226b61 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -1,10 +1,11 @@
saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \
- saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \
- saa7134-vbi.o saa7134-video.o saa7134-input.o
+ saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o \
+ saa7134-video.o saa7134-input.o
obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \
- saa6752hs.o saa7134-alsa.o
+ saa6752hs.o saa7134-alsa.o \
+ saa7134-oss.o
obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
EXTRA_CFLAGS += -I$(src)/..
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 4f3c423..5707c66 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -30,7 +30,9 @@
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include <sound/initval.h>
+#include <linux/interrupt.h>
#include "saa7134.h"
#include "saa7134-reg.h"
@@ -56,6 +58,8 @@ static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
+int position;
+
#define dprintk(fmt, arg...) if (debug) \
printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
@@ -68,7 +72,7 @@ typedef struct snd_card_saa7134 {
int mixer_volume[MIXER_ADDR_LAST+1][2];
int capture_source[MIXER_ADDR_LAST+1][2];
struct pci_dev *pci;
- struct saa7134_dev *saadev;
+ struct saa7134_dev *dev;
unsigned long iobase;
int irq;
@@ -83,12 +87,10 @@ typedef struct snd_card_saa7134 {
*/
typedef struct snd_card_saa7134_pcm {
- struct saa7134_dev *saadev;
+ struct saa7134_dev *dev;
spinlock_t lock;
- unsigned int pcm_size; /* buffer size */
- unsigned int pcm_count; /* bytes per period */
- unsigned int pcm_bps; /* bytes per second */
+
snd_pcm_substream_t *substream;
} snd_card_saa7134_pcm_t;
@@ -100,13 +102,11 @@ static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
*
* Called when the capture device is released or the buffer overflows
*
- * - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped
- * if we just share dsp_dma_stop and use it here
+ * - Copied verbatim from saa7134-oss's dsp_dma_stop.
*
*/
static void saa7134_dma_stop(struct saa7134_dev *dev)
-
{
dev->dmasound.dma_blk = -1;
dev->dmasound.dma_running = 0;
@@ -118,8 +118,7 @@ static void saa7134_dma_stop(struct saa7134_dev *dev)
*
* Called when preparing the capture device for use
*
- * - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped
- * if we just share dsp_dma_start and use it here
+ * - Copied verbatim from saa7134-oss's dsp_dma_start.
*
*/
@@ -170,9 +169,9 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
dev->dmasound.bufsize, dev->dmasound.blocks);
+ spin_unlock(&dev->slock);
snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
- saa7134_dma_stop(dev);
- goto done;
+ return;
}
/* next block addr */
@@ -194,6 +193,7 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
snd_pcm_period_elapsed(dev->dmasound.substream);
spin_lock(&dev->slock);
}
+
done:
spin_unlock(&dev->slock);
@@ -209,7 +209,9 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
{
- struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
+ struct saa7134_dmasound *dmasound = dev_id;
+ struct saa7134_dev *dev = dmasound->priv_data;
+
unsigned long report, status;
int loop, handled = 0;
@@ -248,56 +250,23 @@ static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
int cmd)
{
snd_pcm_runtime_t *runtime = substream->runtime;
- snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
- struct saa7134_dev *dev=saapcm->saadev;
+ snd_card_saa7134_pcm_t *pcm = runtime->private_data;
+ struct saa7134_dev *dev=pcm->dev;
int err = 0;
- spin_lock_irq(&dev->slock);
- if (cmd == SNDRV_PCM_TRIGGER_START) {
+ spin_lock(&dev->slock);
+ if (cmd == SNDRV_PCM_TRIGGER_START) {
/* start dma */
saa7134_dma_start(dev);
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
+ } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
/* stop dma */
saa7134_dma_stop(dev);
- } else {
- err = -EINVAL;
- }
- spin_unlock_irq(&dev->slock);
-
- return err;
-}
-
-/*
- * DMA buffer config
- *
- * Sets the values that will later be used as the size of the buffer,
- * size of the fragments, and total number of fragments.
- * Must be called during the preparation stage, before memory is
- * allocated
- *
- * - Copied verbatim from saa7134-oss. Can be dropped
- * if we just share dsp_buffer_conf from OSS.
- */
+ } else {
+ err = -EINVAL;
+ }
+ spin_unlock(&dev->slock);
-static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
-{
- if (blksize < 0x100)
- blksize = 0x100;
- if (blksize > 0x10000)
- blksize = 0x10000;
-
- if (blocks < 2)
- blocks = 2;
- if ((blksize * blocks) > 1024*1024)
- blocks = 1024*1024 / blksize;
-
- dev->dmasound.blocks = blocks;
- dev->dmasound.blksize = blksize;
- dev->dmasound.bufsize = blksize * blocks;
-
- dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
- blocks,blksize,blksize * blocks / 1024);
- return 0;
+ return err;
}
/*
@@ -307,16 +276,16 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
* ALSA, but I was unable to use ALSA's own DMA, and had to force the
* usage of V4L's
*
- * - Copied verbatim from saa7134-oss. Can be dropped
- * if we just share dsp_buffer_init from OSS.
+ * - Copied verbatim from saa7134-oss.
+ *
*/
static int dsp_buffer_init(struct saa7134_dev *dev)
{
int err;
- if (!dev->dmasound.bufsize)
- BUG();
+ BUG_ON(!dev->dmasound.bufsize);
+
videobuf_dma_init(&dev->dmasound.dma);
err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
(dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
@@ -326,6 +295,28 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
}
/*
+ * DMA buffer release
+ *
+ * Called after closing the device, during snd_card_saa7134_capture_close
+ *
+ */
+
+static int dsp_buffer_free(struct saa7134_dev *dev)
+{
+ if (!dev->dmasound.blksize)
+ BUG();
+
+ videobuf_dma_free(&dev->dmasound.dma);
+
+ dev->dmasound.blocks = 0;
+ dev->dmasound.blksize = 0;
+ dev->dmasound.bufsize = 0;
+
+ return 0;
+}
+
+
+/*
* ALSA PCM preparation
*
* - One of the ALSA capture callbacks.
@@ -340,84 +331,30 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
- int err, bswap, sign;
+ int bswap, sign;
u32 fmt, control;
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
struct saa7134_dev *dev;
- snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
- unsigned int bps;
- unsigned long size;
- unsigned count;
-
- size = snd_pcm_lib_buffer_bytes(substream);
- count = snd_pcm_lib_period_bytes(substream);
-
- saapcm->saadev->dmasound.substream = substream;
- bps = runtime->rate * runtime->channels;
- bps *= snd_pcm_format_width(runtime->format);
- bps /= 8;
- if (bps <= 0)
- return -EINVAL;
- saapcm->pcm_bps = bps;
- saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream);
- saapcm->pcm_count = snd_pcm_lib_period_bytes(substream);
-
+ snd_card_saa7134_pcm_t *pcm = runtime->private_data;
- dev=saa7134->saadev;
+ pcm->dev->dmasound.substream = substream;
- dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count));
+ dev = saa7134->dev;
- err = dsp_buffer_init(dev);
- if (0 != err)
- goto fail2;
-
- /* prepare buffer */
- if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
- return err;
- if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
- goto fail1;
- if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
- dev->dmasound.dma.sglist,
- dev->dmasound.dma.sglen,
- 0)))
- goto fail2;
-
-
-
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_U8:
- case SNDRV_PCM_FORMAT_S8:
+ if (snd_pcm_format_width(runtime->format) == 8)
fmt = 0x00;
- break;
- case SNDRV_PCM_FORMAT_U16_LE:
- case SNDRV_PCM_FORMAT_U16_BE:
- case SNDRV_PCM_FORMAT_S16_LE:
- case SNDRV_PCM_FORMAT_S16_BE:
+ else
fmt = 0x01;
- break;
- default:
- err = -EINVAL;
- return 1;
- }
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S8:
- case SNDRV_PCM_FORMAT_S16_LE:
- case SNDRV_PCM_FORMAT_S16_BE:
+ if (snd_pcm_format_signed(runtime->format))
sign = 1;
- break;
- default:
+ else
sign = 0;
- break;
- }
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_U16_BE:
- case SNDRV_PCM_FORMAT_S16_BE:
- bswap = 1; break;
- default:
- bswap = 0; break;
- }
+ if (snd_pcm_format_big_endian(runtime->format))
+ bswap = 1;
+ else
+ bswap = 0;
switch (dev->pci->device) {
case PCI_DEVICE_ID_PHILIPS_SAA7134:
@@ -445,7 +382,6 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
fmt |= 0x04;
saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1);
saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
- //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210);
break;
}
@@ -459,12 +395,6 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
if (bswap)
control |= SAA7134_RS_CONTROL_BSWAP;
- /* I should be able to use runtime->dma_addr in the control
- byte, but it doesn't work. So I allocate the DMA using the
- V4L functions, and force ALSA to use that as the DMA area */
-
- runtime->dma_area = dev->dmasound.dma.vmalloc;
-
saa_writel(SAA7134_RS_BA1(6),0);
saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
saa_writel(SAA7134_RS_PITCH(6),0);
@@ -473,12 +403,6 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
dev->dmasound.rate = runtime->rate;
return 0;
- fail2:
- saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
- fail1:
- videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
- return err;
-
}
@@ -496,10 +420,8 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
- snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
- struct saa7134_dev *dev=saapcm->saadev;
-
-
+ snd_card_saa7134_pcm_t *pcm = runtime->private_data;
+ struct saa7134_dev *dev=pcm->dev;
if (dev->dmasound.read_count) {
dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream);
@@ -540,9 +462,9 @@ static snd_pcm_hardware_t snd_card_saa7134_capture =
static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
{
- snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
+ snd_card_saa7134_pcm_t *pcm = runtime->private_data;
- kfree(saapcm);
+ kfree(pcm);
}
@@ -552,17 +474,76 @@ static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
* - One of the ALSA capture callbacks.
*
* Called on initialization, right before the PCM preparation
- * Usually used in ALSA to allocate the DMA, but since we don't use the
- * ALSA DMA it does nothing
*
*/
static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
snd_pcm_hw_params_t * hw_params)
{
+ snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
+ struct saa7134_dev *dev;
+ unsigned int period_size, periods;
+ int err;
- return 0;
+ period_size = params_period_bytes(hw_params);
+ periods = params_periods(hw_params);
+
+ snd_assert(period_size >= 0x100 && period_size <= 0x10000,
+ return -EINVAL);
+ snd_assert(periods >= 2, return -EINVAL);
+ snd_assert(period_size * periods <= 1024 * 1024, return -EINVAL);
+ dev = saa7134->dev;
+
+ if (dev->dmasound.blocks == periods &&
+ dev->dmasound.blksize == period_size)
+ return 0;
+
+ /* release the old buffer */
+ if (substream->runtime->dma_area) {
+ saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
+ videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+ dsp_buffer_free(dev);
+ substream->runtime->dma_area = NULL;
+ }
+ dev->dmasound.blocks = periods;
+ dev->dmasound.blksize = period_size;
+ dev->dmasound.bufsize = period_size * periods;
+
+ err = dsp_buffer_init(dev);
+ if (0 != err) {
+ dev->dmasound.blocks = 0;
+ dev->dmasound.blksize = 0;
+ dev->dmasound.bufsize = 0;
+ return err;
+ }
+
+ if (0 != (err = videobuf_dma_pci_map(dev->pci, &dev->dmasound.dma))) {
+ dsp_buffer_free(dev);
+ return err;
+ }
+ if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) {
+ videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+ dsp_buffer_free(dev);
+ return err;
+ }
+ if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
+ dev->dmasound.dma.sglist,
+ dev->dmasound.dma.sglen,
+ 0))) {
+ saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
+ videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+ dsp_buffer_free(dev);
+ return err;
+ }
+
+ /* I should be able to use runtime->dma_addr in the control
+ byte, but it doesn't work. So I allocate the DMA using the
+ V4L functions, and force ALSA to use that as the DMA area */
+
+ substream->runtime->dma_area = dev->dmasound.dma.vmalloc;
+
+ return 1;
}
@@ -572,33 +553,23 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
* - One of the ALSA capture callbacks.
*
* Called after closing the device, but before snd_card_saa7134_capture_close
- * Usually used in ALSA to free the DMA, but since we don't use the
- * ALSA DMA I'm almost sure this isn't necessary.
+ * It stops the DMA audio and releases the buffers.
*
*/
static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
{
- return 0;
-}
-
-/*
- * DMA buffer release
- *
- * Called after closing the device, during snd_card_saa7134_capture_close
- *
- */
-
-static int dsp_buffer_free(struct saa7134_dev *dev)
-{
- if (!dev->dmasound.blksize)
- BUG();
+ snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
+ struct saa7134_dev *dev;
- videobuf_dma_free(&dev->dmasound.dma);
+ dev = saa7134->dev;
- dev->dmasound.blocks = 0;
- dev->dmasound.blksize = 0;
- dev->dmasound.bufsize = 0;
+ if (substream->runtime->dma_area) {
+ saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
+ videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+ dsp_buffer_free(dev);
+ substream->runtime->dma_area = NULL;
+ }
return 0;
}
@@ -608,21 +579,12 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
*
* - One of the ALSA capture callbacks.
*
- * Called after closing the device. It stops the DMA audio and releases
- * the buffers
+ * Called after closing the device.
*
*/
static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
{
- snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream);
- struct saa7134_dev *dev = chip->saadev;
-
- /* unlock buffer */
- saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
- videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
-
- dsp_buffer_free(dev);
return 0;
}
@@ -639,29 +601,28 @@ static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
- snd_card_saa7134_pcm_t *saapcm;
+ snd_card_saa7134_pcm_t *pcm;
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
- struct saa7134_dev *dev = saa7134->saadev;
+ struct saa7134_dev *dev = saa7134->dev;
int err;
down(&dev->dmasound.lock);
- dev->dmasound.afmt = SNDRV_PCM_FORMAT_U8;
- dev->dmasound.channels = 2;
dev->dmasound.read_count = 0;
dev->dmasound.read_offset = 0;
up(&dev->dmasound.lock);
- saapcm = kzalloc(sizeof(*saapcm), GFP_KERNEL);
- if (saapcm == NULL)
+ pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
+ if (pcm == NULL)
return -ENOMEM;
- saapcm->saadev=saa7134->saadev;
- spin_lock_init(&saapcm->lock);
+ pcm->dev=saa7134->dev;
- saapcm->substream = substream;
- runtime->private_data = saapcm;
+ spin_lock_init(&pcm->lock);
+
+ pcm->substream = substream;
+ runtime->private_data = pcm;
runtime->private_free = snd_card_saa7134_runtime_free;
runtime->hw = snd_card_saa7134_capture;
@@ -736,7 +697,6 @@ static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change, addr = kcontrol->private_value;
int left, right;
@@ -750,12 +710,12 @@ static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
right = 0;
if (right > 20)
right = 20;
- spin_lock_irqsave(&chip->mixer_lock, flags);
+ spin_lock_irq(&chip->mixer_lock);
change = chip->mixer_volume[addr][0] != left ||
chip->mixer_volume[addr][1] != right;
chip->mixer_volume[addr][0] = left;
chip->mixer_volume[addr][1] = right;
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ spin_unlock_irq(&chip->mixer_lock);
return change;
}
@@ -777,38 +737,37 @@ static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_
static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int addr = kcontrol->private_value;
- spin_lock_irqsave(&chip->mixer_lock, flags);
+ spin_lock_irq(&chip->mixer_lock);
ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ spin_unlock_irq(&chip->mixer_lock);
+
return 0;
}
static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change, addr = kcontrol->private_value;
int left, right;
u32 anabar, xbarin;
int analog_io, rate;
struct saa7134_dev *dev;
- dev = chip->saadev;
+ dev = chip->dev;
left = ucontrol->value.integer.value[0] & 1;
right = ucontrol->value.integer.value[1] & 1;
- spin_lock_irqsave(&chip->mixer_lock, flags);
+ spin_lock_irq(&chip->mixer_lock);
change = chip->capture_source[addr][0] != left ||
chip->capture_source[addr][1] != right;
chip->capture_source[addr][0] = left;
chip->capture_source[addr][1] = right;
dev->dmasound.input=addr;
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ spin_unlock_irq(&chip->mixer_lock);
if (change) {
@@ -898,43 +857,44 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
return 0;
}
-static int snd_saa7134_free(snd_card_saa7134_t *chip)
+static void snd_saa7134_free(snd_card_t * card)
{
- return 0;
-}
+ snd_card_saa7134_t *chip = card->private_data;
+
+ if (chip->dev->dmasound.priv_data == NULL)
+ return;
+
+ if (chip->irq >= 0) {
+ synchronize_irq(chip->irq);
+ free_irq(chip->irq, &chip->dev->dmasound);
+ }
+
+ chip->dev->dmasound.priv_data = NULL;
-static int snd_saa7134_dev_free(snd_device_t *device)
-{
- snd_card_saa7134_t *chip = device->device_data;
- return snd_saa7134_free(chip);
}
/*
* ALSA initialization
*
- * Called by saa7134-core, it creates the basic structures and registers
- * the ALSA devices
+ * Called by the init routine, once for each saa7134 device present,
+ * it creates the basic structures and registers the ALSA devices
*
*/
-int alsa_card_saa7134_create (struct saa7134_dev *saadev)
+int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
{
- static int dev;
snd_card_t *card;
snd_card_saa7134_t *chip;
int err;
- static snd_device_ops_t ops = {
- .dev_free = snd_saa7134_dev_free,
- };
- if (dev >= SNDRV_CARDS)
+ if (devnum >= SNDRV_CARDS)
return -ENODEV;
- if (!enable[dev])
+ if (!enable[devnum])
return -ENODEV;
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t));
if (card == NULL)
return -ENOMEM;
@@ -943,34 +903,33 @@ int alsa_card_saa7134_create (struct saa7134_dev *saadev)
/* Card "creation" */
- chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- return -ENOMEM;
- }
+ card->private_free = snd_saa7134_free;
+ chip = (snd_card_saa7134_t *) card->private_data;
spin_lock_init(&chip->lock);
spin_lock_init(&chip->mixer_lock);
- chip->saadev = saadev;
+ chip->dev = dev;
chip->card = card;
- chip->pci = saadev->pci;
- chip->irq = saadev->pci->irq;
- chip->iobase = pci_resource_start(saadev->pci, 0);
+ chip->pci = dev->pci;
+ chip->iobase = pci_resource_start(dev->pci, 0);
- err = request_irq(saadev->pci->irq, saa7134_alsa_irq,
- SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev);
+
+ err = request_irq(dev->pci->irq, saa7134_alsa_irq,
+ SA_SHIRQ | SA_INTERRUPT, dev->name,
+ (void*) &dev->dmasound);
if (err < 0) {
printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n",
- saadev->name, saadev->pci->irq);
+ dev->name, dev->pci->irq);
goto __nodev;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- goto __nodev;
- }
+ chip->irq = dev->pci->irq;
+
+ init_MUTEX(&dev->dmasound.lock);
if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
goto __nodev;
@@ -984,16 +943,15 @@ int alsa_card_saa7134_create (struct saa7134_dev *saadev)
strcpy(card->shortname, "SAA7134");
sprintf(card->longname, "%s at 0x%lx irq %d",
- chip->saadev->name, chip->iobase, chip->irq);
+ chip->dev->name, chip->iobase, chip->irq);
if ((err = snd_card_register(card)) == 0) {
- snd_saa7134_cards[dev] = card;
+ snd_saa7134_cards[devnum] = card;
return 0;
}
__nodev:
snd_card_free(card);
- kfree(chip);
return err;
}
@@ -1007,21 +965,29 @@ __nodev:
static int saa7134_alsa_init(void)
{
- struct saa7134_dev *saadev = NULL;
- struct list_head *list;
+ struct saa7134_dev *dev = NULL;
+ struct list_head *list;
- printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
+ position = 0;
- list_for_each(list,&saa7134_devlist) {
- saadev = list_entry(list, struct saa7134_dev, devlist);
- alsa_card_saa7134_create(saadev);
- }
+ printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
- if (saadev == NULL)
+ list_for_each(list,&saa7134_devlist) {
+ dev = list_entry(list, struct saa7134_dev, devlist);
+ if (dev->dmasound.priv_data == NULL) {
+ dev->dmasound.priv_data = dev;
+ alsa_card_saa7134_create(dev,position);
+ position++;
+ } else {
+ printk(KERN_ERR "saa7134 ALSA: DMA sound is being handled by OSS. ignoring %s\n",dev->name);
+ return -EBUSY;
+ }
+ }
+
+ if (dev == NULL)
printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
return 0;
-
}
/*
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 663d03e..75abc20 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -2529,6 +2529,32 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
}},
},
+ [SAA7134_BOARD_MSI_TVATANYWHERE_PLUS] = {
+ .name = "MSI TV@Anywhere plus",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 0,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ },
+ },
};
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -2970,6 +2996,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x2018,
.driver_data = SAA7134_BOARD_PHILIPS_TIGER,
},{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1462,
+ .subdevice = 0x6231,
+ .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
+ },{
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 19b8874..4275d2d 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -53,13 +53,13 @@ static unsigned int gpio_tracking = 0;
module_param(gpio_tracking, int, 0644);
MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
-static unsigned int oss = 0;
-module_param(oss, int, 0444);
-MODULE_PARM_DESC(oss,"register oss devices (default: no)");
-
static unsigned int alsa = 0;
-module_param(alsa, int, 0444);
-MODULE_PARM_DESC(alsa,"register alsa devices (default: no)");
+module_param(alsa, int, 0644);
+MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]");
+
+static unsigned int oss = 0;
+module_param(oss, int, 0644);
+MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]");
static unsigned int latency = UNSET;
module_param(latency, int, 0444);
@@ -68,24 +68,18 @@ MODULE_PARM_DESC(latency,"pci latency timer");
static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-static unsigned int dsp_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
static unsigned int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
static unsigned int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
module_param_array(video_nr, int, NULL, 0444);
module_param_array(vbi_nr, int, NULL, 0444);
module_param_array(radio_nr, int, NULL, 0444);
-module_param_array(dsp_nr, int, NULL, 0444);
-module_param_array(mixer_nr, int, NULL, 0444);
module_param_array(tuner, int, NULL, 0444);
module_param_array(card, int, NULL, 0444);
MODULE_PARM_DESC(video_nr, "video device number");
MODULE_PARM_DESC(vbi_nr, "vbi device number");
MODULE_PARM_DESC(radio_nr, "radio device number");
-MODULE_PARM_DESC(dsp_nr, "oss dsp device number");
-MODULE_PARM_DESC(mixer_nr, "oss mixer device number");
MODULE_PARM_DESC(tuner, "tuner type");
MODULE_PARM_DESC(card, "card type");
@@ -195,6 +189,7 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
static int need_empress;
static int need_dvb;
static int need_alsa;
+static int need_oss;
static int pending_call(struct notifier_block *self, unsigned long state,
void *module)
@@ -208,6 +203,8 @@ static int pending_call(struct notifier_block *self, unsigned long state,
request_module("saa7134-dvb");
if (need_alsa)
request_module("saa7134-alsa");
+ if (need_oss)
+ request_module("saa7134-oss");
return NOTIFY_DONE;
}
@@ -218,10 +215,11 @@ static struct notifier_block pending_notifier = {
static void request_module_depend(char *name, int *flag)
{
+ int err;
switch (THIS_MODULE->state) {
case MODULE_STATE_COMING:
if (!pending_registered) {
- register_module_notifier(&pending_notifier);
+ err = register_module_notifier(&pending_notifier);
pending_registered = 1;
}
*flag = 1;
@@ -578,12 +576,14 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
goto out;
}
- /* If alsa support is active and we get a sound report, exit
- and let the saa7134-alsa module deal with it */
+ /* If dmasound support is active and we get a sound report, exit
+ and let the saa7134-alsa/oss module deal with it */
- if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && alsa) {
+ if ((report & SAA7134_IRQ_REPORT_DONE_RA3) &&
+ (dev->dmasound.priv_data != NULL) )
+ {
if (irq_debug > 1)
- printk(KERN_DEBUG "%s/irq: ignoring interrupt for ALSA\n",
+ printk(KERN_DEBUG "%s/irq: ignoring interrupt for DMA sound\n",
dev->name);
goto out;
}
@@ -609,12 +609,6 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
card_has_mpeg(dev))
saa7134_irq_ts_done(dev,status);
- if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) {
- if (oss) {
- saa7134_irq_oss_done(dev,status);
- }
- }
-
if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
SAA7134_IRQ_REPORT_GPIO18)) &&
dev->remote)
@@ -689,14 +683,6 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
* audio will not work.
*/
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- saa7134_oss_init1(dev);
- break;
- }
-
/* enable peripheral devices */
saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
@@ -728,8 +714,6 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
SAA7134_IRQ2_INTE_GPIO18A |
SAA7134_IRQ2_INTE_GPIO16 );
- else if (dev->has_remote == SAA7134_REMOTE_I2C)
- request_module("ir-kbd-i2c");
saa_writel(SAA7134_IRQ1, 0);
saa_writel(SAA7134_IRQ2, irq2_mask);
@@ -742,13 +726,6 @@ static int saa7134_hwfini(struct saa7134_dev *dev)
{
dprintk("hwfini\n");
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- saa7134_oss_fini(dev);
- break;
- }
if (card_has_mpeg(dev))
saa7134_ts_fini(dev);
saa7134_input_fini(dev);
@@ -986,11 +963,12 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
if (card_is_dvb(dev))
request_module_depend("saa7134-dvb",&need_dvb);
- if (!oss && alsa) {
- dprintk("Requesting ALSA module\n");
+
+ if (alsa)
request_module_depend("saa7134-alsa",&need_alsa);
- }
+ if (oss)
+ request_module_depend("saa7134-oss",&need_oss);
v4l2_prio_init(&dev->prio);
@@ -1024,32 +1002,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
dev->name,dev->radio_dev->minor & 0x1f);
}
- /* register oss devices */
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- if (oss) {
- err = dev->dmasound.minor_dsp =
- register_sound_dsp(&saa7134_dsp_fops,
- dsp_nr[dev->nr]);
- if (err < 0) {
- goto fail4;
- }
- printk(KERN_INFO "%s: registered device dsp%d\n",
- dev->name,dev->dmasound.minor_dsp >> 4);
-
- err = dev->dmasound.minor_mixer =
- register_sound_mixer(&saa7134_mixer_fops,
- mixer_nr[dev->nr]);
- if (err < 0)
- goto fail5;
- printk(KERN_INFO "%s: registered device mixer%d\n",
- dev->name,dev->dmasound.minor_mixer >> 4);
- }
- break;
- }
-
/* everything worked */
pci_set_drvdata(pci_dev,dev);
saa7134_devcount++;
@@ -1064,17 +1016,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
/* check for signal */
saa7134_irq_video_intl(dev);
+
return 0;
- fail5:
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- if (oss)
- unregister_sound_dsp(dev->dmasound.minor_dsp);
- break;
- }
fail4:
saa7134_unregister_video(dev);
saa7134_i2c_unregister(dev);
@@ -1125,19 +1069,16 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
saa7134_devcount--;
saa7134_i2c_unregister(dev);
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- if (oss) {
- unregister_sound_mixer(dev->dmasound.minor_mixer);
- unregister_sound_dsp(dev->dmasound.minor_dsp);
- }
- break;
- }
saa7134_unregister_video(dev);
- /* release ressources */
+ /* the DMA sound modules should be unloaded before reaching
+ this, but just in case they are still present... */
+ if (dev->dmasound.priv_data != NULL) {
+ free_irq(pci_dev->irq, &dev->dmasound);
+ dev->dmasound.priv_data = NULL;
+ }
+
+ /* release resources */
free_irq(pci_dev->irq, dev);
iounmap(dev->lmmio);
release_mem_region(pci_resource_start(pci_dev,0),
@@ -1225,7 +1166,7 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients);
EXPORT_SYMBOL(saa7134_devlist);
EXPORT_SYMBOL(saa7134_boards);
-/* ----------------- For ALSA -------------------------------- */
+/* ----------------- for the DMA sound modules --------------- */
EXPORT_SYMBOL(saa7134_pgtable_free);
EXPORT_SYMBOL(saa7134_pgtable_build);
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 329accd..e648cc3 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -485,64 +485,6 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
};
-static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
- [ 0x59 ] = KEY_MUTE,
- [ 0x4a ] = KEY_POWER,
-
- [ 0x18 ] = KEY_TEXT,
- [ 0x26 ] = KEY_TV,
- [ 0x3d ] = KEY_PRINT,
-
- [ 0x48 ] = KEY_RED,
- [ 0x04 ] = KEY_GREEN,
- [ 0x11 ] = KEY_YELLOW,
- [ 0x00 ] = KEY_BLUE,
-
- [ 0x2d ] = KEY_VOLUMEUP,
- [ 0x1e ] = KEY_VOLUMEDOWN,
-
- [ 0x49 ] = KEY_MENU,
-
- [ 0x16 ] = KEY_CHANNELUP,
- [ 0x17 ] = KEY_CHANNELDOWN,
-
- [ 0x20 ] = KEY_UP,
- [ 0x21 ] = KEY_DOWN,
- [ 0x22 ] = KEY_LEFT,
- [ 0x23 ] = KEY_RIGHT,
- [ 0x0d ] = KEY_SELECT,
-
-
-
- [ 0x08 ] = KEY_BACK,
- [ 0x07 ] = KEY_REFRESH,
-
- [ 0x2f ] = KEY_ZOOM,
- [ 0x29 ] = KEY_RECORD,
-
- [ 0x4b ] = KEY_PAUSE,
- [ 0x4d ] = KEY_REWIND,
- [ 0x2e ] = KEY_PLAY,
- [ 0x4e ] = KEY_FORWARD,
- [ 0x53 ] = KEY_PREVIOUS,
- [ 0x4c ] = KEY_STOP,
- [ 0x54 ] = KEY_NEXT,
-
- [ 0x69 ] = KEY_KP0,
- [ 0x6a ] = KEY_KP1,
- [ 0x6b ] = KEY_KP2,
- [ 0x6c ] = KEY_KP3,
- [ 0x6d ] = KEY_KP4,
- [ 0x6e ] = KEY_KP5,
- [ 0x6f ] = KEY_KP6,
- [ 0x70 ] = KEY_KP7,
- [ 0x71 ] = KEY_KP8,
- [ 0x72 ] = KEY_KP9,
-
- [ 0x74 ] = KEY_CHANNEL,
- [ 0x0a ] = KEY_BACKSPACE,
-};
-
/* Mapping for the 28 key remote control as seen at
http://www.sednacomputer.com/photo/cardbus-tv.jpg
Pavel Mihaylov <bin@bash.info> */
@@ -635,57 +577,6 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
-/* The new pinnacle PCTV remote (with the colored buttons)
- *
- * Ricardo Cerqueira <v4l@cerqueira.org>
- */
-
-static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char b[4];
- unsigned int start = 0,parity = 0,code = 0;
-
- /* poll IR chip */
- if (4 != i2c_master_recv(&ir->c,b,4)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
-
- for (start = 0; start<4; start++) {
- if (b[start] == 0x80) {
- code=b[(start+3)%4];
- parity=b[(start+2)%4];
- }
- }
-
- /* Empty Request */
- if (parity==0)
- return 0;
-
- /* Repeating... */
- if (ir->old == parity)
- return 0;
-
-
- ir->old = parity;
-
- /* Reduce code value to fit inside IR_KEYTAB_SIZE
- *
- * this is the only value that results in 42 unique
- * codes < 128
- */
-
- code %= 0x88;
-
- *ir_raw = code;
- *ir_key = code;
-
- i2cdprintk("Pinnacle PCTV key %02x\n", code);
-
- return 1;
-}
-
-
void saa7134_input_irq(struct saa7134_dev *dev)
{
struct saa7134_ir *ir = dev->remote;
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index fd53dfc..fd9ed11 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -4,6 +4,8 @@
* oss dsp interface
*
* (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ * 2005 conversion to standalone module:
+ * Ricardo Cerqueira <v4l@cerqueira.org>
*
* 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
@@ -25,7 +27,9 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
+#include <linux/interrupt.h>
#include <linux/slab.h>
+#include <linux/sound.h>
#include <linux/soundcard.h>
#include "saa7134-reg.h"
@@ -33,15 +37,23 @@
/* ------------------------------------------------------------------ */
-static unsigned int oss_debug = 0;
-module_param(oss_debug, int, 0644);
-MODULE_PARM_DESC(oss_debug,"enable debug messages [oss]");
+static unsigned int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,"enable debug messages [oss]");
-static unsigned int oss_rate = 0;
-module_param(oss_rate, int, 0444);
-MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
+static unsigned int rate = 0;
+module_param(rate, int, 0444);
+MODULE_PARM_DESC(rate,"sample rate (valid are: 32000,48000)");
-#define dprintk(fmt, arg...) if (oss_debug) \
+static unsigned int dsp_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
+MODULE_PARM_DESC(dsp_nr, "device numbers for SAA7134 capture interface(s).");
+module_param_array(dsp_nr, int, NULL, 0444);
+
+static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
+MODULE_PARM_DESC(mixer_nr, "mixer numbers for SAA7134 capture interface(s).");
+module_param_array(mixer_nr, int, NULL, 0444);
+
+#define dprintk(fmt, arg...) if (debug) \
printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
@@ -369,7 +381,7 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
int __user *p = argp;
int val = 0;
- if (oss_debug > 1)
+ if (debug > 1)
saa7134_print_ioctl(dev->name,cmd);
switch (cmd) {
case OSS_GETVERSION:
@@ -665,7 +677,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
void __user *argp = (void __user *) arg;
int __user *p = argp;
- if (oss_debug > 1)
+ if (debug > 1)
saa7134_print_ioctl(dev->name,cmd);
switch (cmd) {
case OSS_GETVERSION:
@@ -768,8 +780,41 @@ struct file_operations saa7134_mixer_fops = {
/* ------------------------------------------------------------------ */
+static irqreturn_t saa7134_oss_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct saa7134_dmasound *dmasound = dev_id;
+ struct saa7134_dev *dev = dmasound->priv_data;
+ unsigned long report, status;
+ int loop, handled = 0;
+
+ for (loop = 0; loop < 10; loop++) {
+ report = saa_readl(SAA7134_IRQ_REPORT);
+ status = saa_readl(SAA7134_IRQ_STATUS);
+
+ if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
+ handled = 1;
+ saa_writel(SAA7134_IRQ_REPORT,report);
+ saa7134_irq_oss_done(dev, status);
+ } else {
+ goto out;
+ }
+ }
+
+ if (loop == 10) {
+ dprintk("error! looping IRQ!");
+ }
+out:
+ return IRQ_RETVAL(handled);
+}
+
int saa7134_oss_init1(struct saa7134_dev *dev)
{
+
+ if ((request_irq(dev->pci->irq, saa7134_oss_irq,
+ SA_SHIRQ | SA_INTERRUPT, dev->name,
+ (void*) &dev->dmasound)) < 0)
+ return -1;
+
/* general */
init_MUTEX(&dev->dmasound.lock);
init_waitqueue_head(&dev->dmasound.wq);
@@ -785,8 +830,8 @@ int saa7134_oss_init1(struct saa7134_dev *dev)
/* dsp */
dev->dmasound.rate = 32000;
- if (oss_rate)
- dev->dmasound.rate = oss_rate;
+ if (rate)
+ dev->dmasound.rate = rate;
dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000;
/* mixer */
@@ -840,7 +885,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
/* next block addr */
next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
saa_writel(reg,next_blk * dev->dmasound.blksize);
- if (oss_debug > 2)
+ if (debug > 2)
dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
(status & 0x10000000) ? "even" : "odd ", next_blk,
next_blk * dev->dmasound.blksize);
@@ -854,6 +899,98 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
spin_unlock(&dev->slock);
}
+int saa7134_dsp_create(struct saa7134_dev *dev)
+{
+ int err;
+
+ err = dev->dmasound.minor_dsp =
+ register_sound_dsp(&saa7134_dsp_fops,
+ dsp_nr[dev->nr]);
+ if (err < 0) {
+ goto fail;
+ }
+ printk(KERN_INFO "%s: registered device dsp%d\n",
+ dev->name,dev->dmasound.minor_dsp >> 4);
+
+ err = dev->dmasound.minor_mixer =
+ register_sound_mixer(&saa7134_mixer_fops,
+ mixer_nr[dev->nr]);
+ if (err < 0)
+ goto fail;
+ printk(KERN_INFO "%s: registered device mixer%d\n",
+ dev->name,dev->dmasound.minor_mixer >> 4);
+
+ return 0;
+
+fail:
+ unregister_sound_dsp(dev->dmasound.minor_dsp);
+ return 0;
+
+
+}
+
+static int saa7134_oss_init(void)
+{
+ struct saa7134_dev *dev = NULL;
+ struct list_head *list;
+
+ printk(KERN_INFO "saa7134 OSS driver for DMA sound loaded\n");
+
+ list_for_each(list,&saa7134_devlist) {
+ dev = list_entry(list, struct saa7134_dev, devlist);
+ if (dev->dmasound.priv_data == NULL) {
+ dev->dmasound.priv_data = dev;
+ saa7134_oss_init1(dev);
+ saa7134_dsp_create(dev);
+ } else {
+ printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name);
+ return -EBUSY;
+ }
+ }
+
+ if (dev == NULL)
+ printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n");
+
+ return 0;
+
+}
+
+void saa7134_oss_exit(void)
+{
+ struct saa7134_dev *dev = NULL;
+ struct list_head *list;
+
+ list_for_each(list,&saa7134_devlist) {
+ dev = list_entry(list, struct saa7134_dev, devlist);
+
+ /* Device isn't registered by OSS, probably ALSA's */
+ if (!dev->dmasound.minor_dsp)
+ continue;
+
+ unregister_sound_mixer(dev->dmasound.minor_mixer);
+ unregister_sound_dsp(dev->dmasound.minor_dsp);
+
+ saa7134_oss_fini(dev);
+
+ if (dev->pci->irq > 0) {
+ synchronize_irq(dev->pci->irq);
+ free_irq(dev->pci->irq,&dev->dmasound);
+ }
+
+ dev->dmasound.priv_data = NULL;
+
+ }
+
+ printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n");
+
+ return;
+}
+
+module_init(saa7134_oss_init);
+module_exit(saa7134_oss_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
+
/* ----------------------------------------------------------- */
/*
* Local variables:
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index fb97274..244e197 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -208,6 +208,7 @@ struct saa7134_format {
#define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS 79
#define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
#define SAA7134_BOARD_PHILIPS_TIGER 81
+#define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS 82
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
@@ -383,6 +384,7 @@ struct saa7134_dmasound {
unsigned int dma_blk;
unsigned int read_offset;
unsigned int read_count;
+ void * priv_data;
snd_pcm_substream_t *substream;
};
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index b2dfe07..61d94dd 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -437,6 +437,10 @@ static void set_audio(struct tuner *t)
t->sgIF = 124;
t->tda8290_easy_mode = 0x20;
mode = "L";
+ } else if (t->std & V4L2_STD_SECAM_LC) {
+ t->sgIF = 20;
+ t->tda8290_easy_mode = 0x40;
+ mode = "LC";
}
tuner_dbg("setting tda8290 to system %s\n", mode);
}
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 73c4041..e58abdf 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -251,7 +251,7 @@ static inline int check_mode(struct tuner *t, char *cmd)
static char pal[] = "-";
module_param_string(pal, pal, sizeof(pal), 0644);
-static char secam[] = "-";
+static char secam[] = "--";
module_param_string(secam, secam, sizeof(secam), 0644);
/* get more precise norm info from insmod option */
@@ -307,8 +307,13 @@ static int tuner_fixup_std(struct tuner *t)
break;
case 'l':
case 'L':
- tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
- t->std = V4L2_STD_SECAM_L;
+ if ((secam[1]=='C')||(secam[1]=='c')) {
+ tuner_dbg ("insmod fixup: SECAM => SECAM-L'\n");
+ t->std = V4L2_STD_SECAM_LC;
+ } else {
+ tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
+ t->std = V4L2_STD_SECAM_L;
+ }
break;
case '-':
/* default parameter, do nothing */
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index d832205..e0c9fdb 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -233,7 +233,7 @@ static struct tunertype tuners[] = {
{ "Ymec TVision TVF-5533MF", Philips, NTSC,
16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
- /* 60-68 */
+ /* 60-69 */
{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
{ "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
@@ -252,6 +252,8 @@ static struct tunertype tuners[] = {
16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 },
{ "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC,
16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 },
+ { "Tena TNF 5335 MF", Philips, NTSC,
+ 16*157.25,16*454.00,0x01,0x02,0x04,0x8e,732 },
};
unsigned const int tuner_count = ARRAY_SIZE(tuners);
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 22f2862..a6936ad 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -5,6 +5,11 @@
*
* Based on saa7115 driver
*
+ * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
+ * - Cleanup
+ * - V4L2 API update
+ * - sound fixes
+ *
* 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
@@ -31,7 +36,7 @@
#include <media/audiochip.h>
MODULE_DESCRIPTION("wm8775 driver");
-MODULE_AUTHOR("Ulf Eklund");
+MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
MODULE_LICENSE("GPL");
#define wm8775_err(fmt, arg...) do { \
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index 7daa0ed..1eab7cf 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -138,9 +138,8 @@ static struct mcp_ops mcp_sa11x0 = {
.disable = mcp_sa11x0_disable,
};
-static int mcp_sa11x0_probe(struct device *dev)
+static int mcp_sa11x0_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct mcp_plat_data *data = pdev->dev.platform_data;
struct mcp *mcp;
int ret;
@@ -165,7 +164,7 @@ static int mcp_sa11x0_probe(struct device *dev)
mcp->dma_telco_rd = DMA_Ser4MCP1Rd;
mcp->dma_telco_wr = DMA_Ser4MCP1Wr;
- dev_set_drvdata(dev, mcp);
+ platform_set_drvdata(pdev, mcp);
if (machine_is_assabet()) {
ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
@@ -202,26 +201,26 @@ static int mcp_sa11x0_probe(struct device *dev)
release:
release_mem_region(0x80060000, 0x60);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
out:
return ret;
}
-static int mcp_sa11x0_remove(struct device *dev)
+static int mcp_sa11x0_remove(struct platform_device *dev)
{
- struct mcp *mcp = dev_get_drvdata(dev);
+ struct mcp *mcp = platform_get_drvdata(dev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
mcp_host_unregister(mcp);
release_mem_region(0x80060000, 0x60);
return 0;
}
-static int mcp_sa11x0_suspend(struct device *dev, pm_message_t state)
+static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state)
{
- struct mcp *mcp = dev_get_drvdata(dev);
+ struct mcp *mcp = platform_get_drvdata(dev);
priv(mcp)->mccr0 = Ser4MCCR0;
priv(mcp)->mccr1 = Ser4MCCR1;
@@ -230,9 +229,9 @@ static int mcp_sa11x0_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int mcp_sa11x0_resume(struct device *dev)
+static int mcp_sa11x0_resume(struct platform_device *dev)
{
- struct mcp *mcp = dev_get_drvdata(dev);
+ struct mcp *mcp = platform_get_drvdata(dev);
Ser4MCCR1 = priv(mcp)->mccr1;
Ser4MCCR0 = priv(mcp)->mccr0;
@@ -243,13 +242,14 @@ static int mcp_sa11x0_resume(struct device *dev)
/*
* The driver for the SA11x0 MCP port.
*/
-static struct device_driver mcp_sa11x0_driver = {
- .name = "sa11x0-mcp",
- .bus = &platform_bus_type,
+static struct platform_driver mcp_sa11x0_driver = {
.probe = mcp_sa11x0_probe,
.remove = mcp_sa11x0_remove,
.suspend = mcp_sa11x0_suspend,
.resume = mcp_sa11x0_resume,
+ .driver = {
+ .name = "sa11x0-mcp",
+ },
};
/*
@@ -257,12 +257,12 @@ static struct device_driver mcp_sa11x0_driver = {
*/
static int __init mcp_sa11x0_init(void)
{
- return driver_register(&mcp_sa11x0_driver);
+ return platform_driver_register(&mcp_sa11x0_driver);
}
static void __exit mcp_sa11x0_exit(void)
{
- driver_unregister(&mcp_sa11x0_driver);
+ platform_driver_unregister(&mcp_sa11x0_driver);
}
module_init(mcp_sa11x0_init);
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
index bc2b72b..11a801b 100644
--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
+++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
@@ -26,8 +26,8 @@
#define SKY_CPUSTATE_VERSION "1.1"
-static int hdpu_cpustate_probe(struct device *ddev);
-static int hdpu_cpustate_remove(struct device *ddev);
+static int hdpu_cpustate_probe(struct platform_device *pdev);
+static int hdpu_cpustate_remove(struct platform_device *pdev);
struct cpustate_t cpustate;
@@ -158,11 +158,12 @@ static int cpustate_read_proc(char *page, char **start, off_t off,
return len;
}
-static struct device_driver hdpu_cpustate_driver = {
- .name = HDPU_CPUSTATE_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver hdpu_cpustate_driver = {
.probe = hdpu_cpustate_probe,
.remove = hdpu_cpustate_remove,
+ .driver = {
+ .name = HDPU_CPUSTATE_NAME,
+ },
};
/*
@@ -187,9 +188,8 @@ static struct miscdevice cpustate_dev = {
&cpustate_fops
};
-static int hdpu_cpustate_probe(struct device *ddev)
+static int hdpu_cpustate_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(ddev);
struct resource *res;
struct proc_dir_entry *proc_de;
int ret;
@@ -217,7 +217,7 @@ static int hdpu_cpustate_probe(struct device *ddev)
return 0;
}
-static int hdpu_cpustate_remove(struct device *ddev)
+static int hdpu_cpustate_remove(struct platform_device *pdev)
{
cpustate.set_addr = NULL;
@@ -232,13 +232,13 @@ static int hdpu_cpustate_remove(struct device *ddev)
static int __init cpustate_init(void)
{
int rc;
- rc = driver_register(&hdpu_cpustate_driver);
+ rc = platform_driver_register(&hdpu_cpustate_driver);
return rc;
}
static void __exit cpustate_exit(void)
{
- driver_unregister(&hdpu_cpustate_driver);
+ platform_driver_unregister(&hdpu_cpustate_driver);
}
module_init(cpustate_init);
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c
index 4bb4617..ea9d5f23 100644
--- a/drivers/misc/hdpuftrs/hdpu_nexus.c
+++ b/drivers/misc/hdpuftrs/hdpu_nexus.c
@@ -22,19 +22,20 @@
#include <linux/platform_device.h>
-static int hdpu_nexus_probe(struct device *ddev);
-static int hdpu_nexus_remove(struct device *ddev);
+static int hdpu_nexus_probe(struct platform_device *pdev);
+static int hdpu_nexus_remove(struct platform_device *pdev);
static struct proc_dir_entry *hdpu_slot_id;
static struct proc_dir_entry *hdpu_chassis_id;
static int slot_id = -1;
static int chassis_id = -1;
-static struct device_driver hdpu_nexus_driver = {
- .name = HDPU_NEXUS_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver hdpu_nexus_driver = {
.probe = hdpu_nexus_probe,
.remove = hdpu_nexus_remove,
+ .driver = {
+ .name = HDPU_NEXUS_NAME,
+ },
};
int hdpu_slot_id_read(char *buffer, char **buffer_location, off_t offset,
@@ -55,9 +56,8 @@ int hdpu_chassis_id_read(char *buffer, char **buffer_location, off_t offset,
return sprintf(buffer, "%d\n", chassis_id);
}
-static int hdpu_nexus_probe(struct device *ddev)
+static int hdpu_nexus_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(ddev);
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -80,7 +80,7 @@ static int hdpu_nexus_probe(struct device *ddev)
return 0;
}
-static int hdpu_nexus_remove(struct device *ddev)
+static int hdpu_nexus_remove(struct platform_device *pdev)
{
slot_id = -1;
chassis_id = -1;
@@ -94,13 +94,13 @@ static int hdpu_nexus_remove(struct device *ddev)
static int __init nexus_init(void)
{
int rc;
- rc = driver_register(&hdpu_nexus_driver);
+ rc = platform_driver_register(&hdpu_nexus_driver);
return rc;
}
static void __exit nexus_exit(void)
{
- driver_unregister(&hdpu_nexus_driver);
+ platform_driver_unregister(&hdpu_nexus_driver);
}
module_init(nexus_init);
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 1e6bdba..166c9b0 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -22,7 +22,6 @@
#include <asm/div64.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/scatterlist.h>
#include <asm/sizes.h>
#include <asm/hardware/amba.h>
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index f31e247..ee8f8a0 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -428,9 +428,8 @@ static irqreturn_t pxamci_detect_irq(int irq, void *devid, struct pt_regs *regs)
return IRQ_HANDLED;
}
-static int pxamci_probe(struct device *dev)
+static int pxamci_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct mmc_host *mmc;
struct pxamci_host *host = NULL;
struct resource *r;
@@ -445,7 +444,7 @@ static int pxamci_probe(struct device *dev)
if (!r)
return -EBUSY;
- mmc = mmc_alloc_host(sizeof(struct pxamci_host), dev);
+ mmc = mmc_alloc_host(sizeof(struct pxamci_host), &pdev->dev);
if (!mmc) {
ret = -ENOMEM;
goto out;
@@ -474,7 +473,7 @@ static int pxamci_probe(struct device *dev)
host->pdata->ocr_mask :
MMC_VDD_32_33|MMC_VDD_33_34;
- host->sg_cpu = dma_alloc_coherent(dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
+ host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
if (!host->sg_cpu) {
ret = -ENOMEM;
goto out;
@@ -511,10 +510,10 @@ static int pxamci_probe(struct device *dev)
if (ret)
goto out;
- dev_set_drvdata(dev, mmc);
+ platform_set_drvdata(pdev, mmc);
if (host->pdata && host->pdata->init)
- host->pdata->init(dev, pxamci_detect_irq, mmc);
+ host->pdata->init(&pdev->dev, pxamci_detect_irq, mmc);
mmc_add_host(mmc);
@@ -527,7 +526,7 @@ static int pxamci_probe(struct device *dev)
if (host->base)
iounmap(host->base);
if (host->sg_cpu)
- dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+ dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
}
if (mmc)
mmc_free_host(mmc);
@@ -535,17 +534,17 @@ static int pxamci_probe(struct device *dev)
return ret;
}
-static int pxamci_remove(struct device *dev)
+static int pxamci_remove(struct platform_device *pdev)
{
- struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
if (mmc) {
struct pxamci_host *host = mmc_priv(mmc);
if (host->pdata && host->pdata->exit)
- host->pdata->exit(dev, mmc);
+ host->pdata->exit(&pdev->dev, mmc);
mmc_remove_host(mmc);
@@ -560,7 +559,7 @@ static int pxamci_remove(struct device *dev)
free_irq(host->irq, host);
pxa_free_dma(host->dma);
iounmap(host->base);
- dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+ dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
release_resource(host->res);
@@ -570,9 +569,9 @@ static int pxamci_remove(struct device *dev)
}
#ifdef CONFIG_PM
-static int pxamci_suspend(struct device *dev, pm_message_t state)
+static int pxamci_suspend(struct platform_device *dev, pm_message_t state)
{
- struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct mmc_host *mmc = platform_get_drvdata(dev);
int ret = 0;
if (mmc)
@@ -581,9 +580,9 @@ static int pxamci_suspend(struct device *dev, pm_message_t state)
return ret;
}
-static int pxamci_resume(struct device *dev)
+static int pxamci_resume(struct platform_device *dev)
{
- struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct mmc_host *mmc = platform_get_drvdata(dev);
int ret = 0;
if (mmc)
@@ -596,23 +595,24 @@ static int pxamci_resume(struct device *dev)
#define pxamci_resume NULL
#endif
-static struct device_driver pxamci_driver = {
- .name = DRIVER_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver pxamci_driver = {
.probe = pxamci_probe,
.remove = pxamci_remove,
.suspend = pxamci_suspend,
.resume = pxamci_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ },
};
static int __init pxamci_init(void)
{
- return driver_register(&pxamci_driver);
+ return platform_driver_register(&pxamci_driver);
}
static void __exit pxamci_exit(void)
{
- driver_unregister(&pxamci_driver);
+ platform_driver_unregister(&pxamci_driver);
}
module_init(pxamci_init);
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index e954b83..c7eb7c2 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -42,7 +42,7 @@
#include "wbsd.h"
#define DRIVER_NAME "wbsd"
-#define DRIVER_VERSION "1.4"
+#define DRIVER_VERSION "1.5"
#ifdef CONFIG_MMC_DEBUG
#define DBG(x...) \
@@ -1932,14 +1932,14 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
* Non-PnP
*/
-static int __devinit wbsd_probe(struct device* dev)
+static int __devinit wbsd_probe(struct platform_device* dev)
{
- return wbsd_init(dev, io, irq, dma, 0);
+ return wbsd_init(&dev->dev, io, irq, dma, 0);
}
-static int __devexit wbsd_remove(struct device* dev)
+static int __devexit wbsd_remove(struct platform_device* dev)
{
- wbsd_shutdown(dev, 0);
+ wbsd_shutdown(&dev->dev, 0);
return 0;
}
@@ -1983,9 +1983,9 @@ static void __devexit wbsd_pnp_remove(struct pnp_dev * dev)
#ifdef CONFIG_PM
-static int wbsd_suspend(struct device *dev, pm_message_t state)
+static int wbsd_suspend(struct platform_device *dev, pm_message_t state)
{
- struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct mmc_host *mmc = platform_get_drvdata(dev);
struct wbsd_host *host;
int ret;
@@ -2005,9 +2005,9 @@ static int wbsd_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int wbsd_resume(struct device *dev)
+static int wbsd_resume(struct platform_device *dev)
{
- struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct mmc_host *mmc = platform_get_drvdata(dev);
struct wbsd_host *host;
if (!mmc)
@@ -2038,14 +2038,15 @@ static int wbsd_resume(struct device *dev)
static struct platform_device *wbsd_device;
-static struct device_driver wbsd_driver = {
- .name = DRIVER_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver wbsd_driver = {
.probe = wbsd_probe,
- .remove = wbsd_remove,
+ .remove = __devexit_p(wbsd_remove),
.suspend = wbsd_suspend,
.resume = wbsd_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ },
};
#ifdef CONFIG_PNP
@@ -2054,7 +2055,7 @@ static struct pnp_driver wbsd_pnp_driver = {
.name = DRIVER_NAME,
.id_table = pnp_dev_table,
.probe = wbsd_pnp_probe,
- .remove = wbsd_pnp_remove,
+ .remove = __devexit_p(wbsd_pnp_remove),
};
#endif /* CONFIG_PNP */
@@ -2085,7 +2086,7 @@ static int __init wbsd_drv_init(void)
if (nopnp)
{
- result = driver_register(&wbsd_driver);
+ result = platform_driver_register(&wbsd_driver);
if (result < 0)
return result;
@@ -2111,7 +2112,7 @@ static void __exit wbsd_drv_exit(void)
{
platform_device_unregister(wbsd_device);
- driver_unregister(&wbsd_driver);
+ platform_driver_unregister(&wbsd_driver);
}
DBG("unloaded\n");
@@ -2127,6 +2128,7 @@ module_param(irq, uint, 0444);
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);
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 48638c8..846a533 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -94,7 +94,7 @@ config MTD_NETSC520
config MTD_TS5500
tristate "JEDEC Flash device mapped on Technologic Systems TS-5500"
- depends on ELAN
+ depends on X86
select MTD_PARTITIONS
select MTD_JEDECPROBE
select MTD_CFI_AMDSTD
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index b7858eb..51f962d 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -63,11 +63,6 @@ struct bast_flash_info {
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-static struct bast_flash_info *to_bast_info(struct device *dev)
-{
- return (struct bast_flash_info *)dev_get_drvdata(dev);
-}
-
static void bast_flash_setrw(int to)
{
unsigned int val;
@@ -87,11 +82,11 @@ static void bast_flash_setrw(int to)
local_irq_restore(flags);
}
-static int bast_flash_remove(struct device *dev)
+static int bast_flash_remove(struct platform_device *pdev)
{
- struct bast_flash_info *info = to_bast_info(dev);
+ struct bast_flash_info *info = platform_get_drvdata(pdev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
if (info == NULL)
return 0;
@@ -116,9 +111,8 @@ static int bast_flash_remove(struct device *dev)
return 0;
}
-static int bast_flash_probe(struct device *dev)
+static int bast_flash_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct bast_flash_info *info;
struct resource *res;
int err = 0;
@@ -131,13 +125,13 @@ static int bast_flash_probe(struct device *dev)
}
memzero(info, sizeof(*info));
- dev_set_drvdata(dev, info);
+ platform_set_drvdata(pdev, info);
res = pdev->resource; /* assume that the flash has one resource */
info->map.phys = res->start;
info->map.size = res->end - res->start + 1;
- info->map.name = dev->bus_id;
+ info->map.name = pdev->dev.bus_id;
info->map.bankwidth = 2;
if (info->map.size > AREA_MAXSIZE)
@@ -199,27 +193,28 @@ static int bast_flash_probe(struct device *dev)
/* fall through to exit error */
exit_error:
- bast_flash_remove(dev);
+ bast_flash_remove(pdev);
return err;
}
-static struct device_driver bast_flash_driver = {
- .name = "bast-nor",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver bast_flash_driver = {
.probe = bast_flash_probe,
.remove = bast_flash_remove,
+ .driver = {
+ .name = "bast-nor",
+ .owner = THIS_MODULE,
+ },
};
static int __init bast_flash_init(void)
{
printk("BAST NOR-Flash Driver, (c) 2004 Simtec Electronics\n");
- return driver_register(&bast_flash_driver);
+ return platform_driver_register(&bast_flash_driver);
}
static void __exit bast_flash_exit(void)
{
- driver_unregister(&bast_flash_driver);
+ platform_driver_unregister(&bast_flash_driver);
}
module_init(bast_flash_init);
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
index fe738fd8..a3ba52f 100644
--- a/drivers/mtd/maps/integrator-flash.c
+++ b/drivers/mtd/maps/integrator-flash.c
@@ -67,9 +67,8 @@ static void armflash_set_vpp(struct map_info *map, int on)
static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL };
-static int armflash_probe(struct device *_dev)
+static int armflash_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
struct flash_platform_data *plat = dev->dev.platform_data;
struct resource *res = dev->resource;
unsigned int size = res->end - res->start + 1;
@@ -138,7 +137,7 @@ static int armflash_probe(struct device *_dev)
}
if (err == 0)
- dev_set_drvdata(&dev->dev, info);
+ platform_set_drvdata(dev, info);
/*
* If we got an error, free all resources.
@@ -163,12 +162,11 @@ static int armflash_probe(struct device *_dev)
return err;
}
-static int armflash_remove(struct device *_dev)
+static int armflash_remove(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
- struct armflash_info *info = dev_get_drvdata(&dev->dev);
+ struct armflash_info *info = platform_get_drvdata(dev);
- dev_set_drvdata(&dev->dev, NULL);
+ platform_set_drvdata(dev, NULL);
if (info) {
if (info->mtd) {
@@ -190,21 +188,22 @@ static int armflash_remove(struct device *_dev)
return 0;
}
-static struct device_driver armflash_driver = {
- .name = "armflash",
- .bus = &platform_bus_type,
+static struct platform_driver armflash_driver = {
.probe = armflash_probe,
.remove = armflash_remove,
+ .driver = {
+ .name = "armflash",
+ },
};
static int __init armflash_init(void)
{
- return driver_register(&armflash_driver);
+ return platform_driver_register(&armflash_driver);
}
static void __exit armflash_exit(void)
{
- driver_unregister(&armflash_driver);
+ platform_driver_unregister(&armflash_driver);
}
module_init(armflash_init);
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index 641eb2b..fc7a78e 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -111,13 +111,12 @@ static void ixp2000_flash_copy_to(struct map_info *map, unsigned long to,
}
-static int ixp2000_flash_remove(struct device *_dev)
+static int ixp2000_flash_remove(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
struct flash_platform_data *plat = dev->dev.platform_data;
- struct ixp2000_flash_info *info = dev_get_drvdata(&dev->dev);
+ struct ixp2000_flash_info *info = platform_get_drvdata(dev);
- dev_set_drvdata(&dev->dev, NULL);
+ platform_set_drvdata(dev, NULL);
if(!info)
return 0;
@@ -143,10 +142,9 @@ static int ixp2000_flash_remove(struct device *_dev)
}
-static int ixp2000_flash_probe(struct device *_dev)
+static int ixp2000_flash_probe(struct platform_device *dev)
{
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
- struct platform_device *dev = to_platform_device(_dev);
struct ixp2000_flash_data *ixp_data = dev->dev.platform_data;
struct flash_platform_data *plat;
struct ixp2000_flash_info *info;
@@ -177,7 +175,7 @@ static int ixp2000_flash_probe(struct device *_dev)
}
memzero(info, sizeof(struct ixp2000_flash_info));
- dev_set_drvdata(&dev->dev, info);
+ platform_set_drvdata(dev, info);
/*
* Tell the MTD layer we're not 1:1 mapped so that it does
@@ -248,25 +246,26 @@ static int ixp2000_flash_probe(struct device *_dev)
return 0;
Error:
- ixp2000_flash_remove(_dev);
+ ixp2000_flash_remove(dev);
return err;
}
-static struct device_driver ixp2000_flash_driver = {
- .name = "IXP2000-Flash",
- .bus = &platform_bus_type,
+static struct platform_driver ixp2000_flash_driver = {
.probe = &ixp2000_flash_probe,
.remove = &ixp2000_flash_remove
+ .driver = {
+ .name = "IXP2000-Flash",
+ },
};
static int __init ixp2000_flash_init(void)
{
- return driver_register(&ixp2000_flash_driver);
+ return platform_driver_register(&ixp2000_flash_driver);
}
static void __exit ixp2000_flash_exit(void)
{
- driver_unregister(&ixp2000_flash_driver);
+ platform_driver_unregister(&ixp2000_flash_driver);
}
module_init(ixp2000_flash_init);
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 56b3a355..a59f802 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -99,13 +99,12 @@ struct ixp4xx_flash_info {
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-static int ixp4xx_flash_remove(struct device *_dev)
+static int ixp4xx_flash_remove(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
struct flash_platform_data *plat = dev->dev.platform_data;
- struct ixp4xx_flash_info *info = dev_get_drvdata(&dev->dev);
+ struct ixp4xx_flash_info *info = platform_get_drvdata(dev);
- dev_set_drvdata(&dev->dev, NULL);
+ platform_set_drvdata(dev, NULL);
if(!info)
return 0;
@@ -130,9 +129,8 @@ static int ixp4xx_flash_remove(struct device *_dev)
return 0;
}
-static int ixp4xx_flash_probe(struct device *_dev)
+static int ixp4xx_flash_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
struct flash_platform_data *plat = dev->dev.platform_data;
struct ixp4xx_flash_info *info;
int err = -1;
@@ -153,7 +151,7 @@ static int ixp4xx_flash_probe(struct device *_dev)
}
memzero(info, sizeof(struct ixp4xx_flash_info));
- dev_set_drvdata(&dev->dev, info);
+ platform_set_drvdata(dev, info);
/*
* Tell the MTD layer we're not 1:1 mapped so that it does
@@ -214,25 +212,26 @@ static int ixp4xx_flash_probe(struct device *_dev)
return 0;
Error:
- ixp4xx_flash_remove(_dev);
+ ixp4xx_flash_remove(dev);
return err;
}
-static struct device_driver ixp4xx_flash_driver = {
- .name = "IXP4XX-Flash",
- .bus = &platform_bus_type,
+static struct platform_driver ixp4xx_flash_driver = {
.probe = ixp4xx_flash_probe,
.remove = ixp4xx_flash_remove,
+ .driver = {
+ .name = "IXP4XX-Flash",
+ },
};
static int __init ixp4xx_flash_init(void)
{
- return driver_register(&ixp4xx_flash_driver);
+ return platform_driver_register(&ixp4xx_flash_driver);
}
static void __exit ixp4xx_flash_exit(void)
{
- driver_unregister(&ixp4xx_flash_driver);
+ platform_driver_unregister(&ixp4xx_flash_driver);
}
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index fd3b4a5..418afff 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -70,11 +70,10 @@ static void omap_set_vpp(struct map_info *map, int enable)
}
}
-static int __devinit omapflash_probe(struct device *dev)
+static int __devinit omapflash_probe(struct platform_device *pdev)
{
int err;
struct omapflash_info *info;
- struct platform_device *pdev = to_platform_device(dev);
struct flash_platform_data *pdata = pdev->dev.platform_data;
struct resource *res = pdev->resource;
unsigned long size = res->end - res->start + 1;
@@ -119,7 +118,7 @@ static int __devinit omapflash_probe(struct device *dev)
#endif
add_mtd_device(info->mtd);
- dev_set_drvdata(&pdev->dev, info);
+ platform_set_drvdata(pdev, info);
return 0;
@@ -133,12 +132,11 @@ out_free_info:
return err;
}
-static int __devexit omapflash_remove(struct device *dev)
+static int __devexit omapflash_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct omapflash_info *info = dev_get_drvdata(&pdev->dev);
+ struct omapflash_info *info = platform_get_drvdata(pdev);
- dev_set_drvdata(&pdev->dev, NULL);
+ platform_set_drvdata(pdev, NULL);
if (info) {
if (info->parts) {
@@ -155,21 +153,22 @@ static int __devexit omapflash_remove(struct device *dev)
return 0;
}
-static struct device_driver omapflash_driver = {
- .name = "omapflash",
- .bus = &platform_bus_type,
+static struct platform_driver omapflash_driver = {
.probe = omapflash_probe,
.remove = __devexit_p(omapflash_remove),
+ .driver = {
+ .name = "omapflash",
+ },
};
static int __init omapflash_init(void)
{
- return driver_register(&omapflash_driver);
+ return platform_driver_register(&omapflash_driver);
}
static void __exit omapflash_exit(void)
{
- driver_unregister(&omapflash_driver);
+ platform_driver_unregister(&omapflash_driver);
}
module_init(omapflash_init);
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index a02eed9..5d3c754 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -56,9 +56,9 @@ struct platram_info {
* device private data to struct platram_info conversion
*/
-static inline struct platram_info *to_platram_info(struct device *dev)
+static inline struct platram_info *to_platram_info(struct platform_device *dev)
{
- return (struct platram_info *)dev_get_drvdata(dev);
+ return (struct platram_info *)platform_get_drvdata(dev);
}
/* platram_setrw
@@ -83,13 +83,13 @@ static inline void platram_setrw(struct platram_info *info, int to)
* called to remove the device from the driver's control
*/
-static int platram_remove(struct device *dev)
+static int platram_remove(struct platform_device *pdev)
{
- struct platram_info *info = to_platram_info(dev);
+ struct platram_info *info = to_platram_info(pdev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
- dev_dbg(dev, "removing device\n");
+ dev_dbg(&pdev->dev, "removing device\n");
if (info == NULL)
return 0;
@@ -130,61 +130,60 @@ static int platram_remove(struct device *dev)
* driver is found.
*/
-static int platram_probe(struct device *dev)
+static int platram_probe(struct platform_device *pdev)
{
- struct platform_device *pd = to_platform_device(dev);
struct platdata_mtd_ram *pdata;
struct platram_info *info;
struct resource *res;
int err = 0;
- dev_dbg(dev, "probe entered\n");
+ dev_dbg(&pdev->dev, "probe entered\n");
- if (dev->platform_data == NULL) {
- dev_err(dev, "no platform data supplied\n");
+ if (pdev->dev.platform_data == NULL) {
+ dev_err(&pdev->dev, "no platform data supplied\n");
err = -ENOENT;
goto exit_error;
}
- pdata = dev->platform_data;
+ pdata = pdev->dev.platform_data;
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (info == NULL) {
- dev_err(dev, "no memory for flash info\n");
+ dev_err(&pdev->dev, "no memory for flash info\n");
err = -ENOMEM;
goto exit_error;
}
memset(info, 0, sizeof(*info));
- dev_set_drvdata(dev, info);
+ platform_set_drvdata(pdev, info);
- info->dev = dev;
+ info->dev = &pdev->dev;
info->pdata = pdata;
/* get the resource for the memory mapping */
- res = platform_get_resource(pd, IORESOURCE_MEM, 0);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
- dev_err(dev, "no memory resource specified\n");
+ dev_err(&pdev->dev, "no memory resource specified\n");
err = -ENOENT;
goto exit_free;
}
- dev_dbg(dev, "got platform resource %p (0x%lx)\n", res, res->start);
+ dev_dbg(&pdev->dev, "got platform resource %p (0x%lx)\n", res, res->start);
/* setup map parameters */
info->map.phys = res->start;
info->map.size = (res->end - res->start) + 1;
- info->map.name = pdata->mapname != NULL ? pdata->mapname : (char *)pd->name;
+ info->map.name = pdata->mapname != NULL ? pdata->mapname : (char *)pdev->name;
info->map.bankwidth = pdata->bankwidth;
/* register our usage of the memory area */
- info->area = request_mem_region(res->start, info->map.size, pd->name);
+ info->area = request_mem_region(res->start, info->map.size, pdev->name);
if (info->area == NULL) {
- dev_err(dev, "failed to request memory region\n");
+ dev_err(&pdev->dev, "failed to request memory region\n");
err = -EIO;
goto exit_free;
}
@@ -192,23 +191,23 @@ static int platram_probe(struct device *dev)
/* remap the memory area */
info->map.virt = ioremap(res->start, info->map.size);
- dev_dbg(dev, "virt %p, %lu bytes\n", info->map.virt, info->map.size);
+ dev_dbg(&pdev->dev, "virt %p, %lu bytes\n", info->map.virt, info->map.size);
if (info->map.virt == NULL) {
- dev_err(dev, "failed to ioremap() region\n");
+ dev_err(&pdev->dev, "failed to ioremap() region\n");
err = -EIO;
goto exit_free;
}
simple_map_init(&info->map);
- dev_dbg(dev, "initialised map, probing for mtd\n");
+ dev_dbg(&pdev->dev, "initialised map, probing for mtd\n");
/* probe for the right mtd map driver */
info->mtd = do_map_probe("map_ram" , &info->map);
if (info->mtd == NULL) {
- dev_err(dev, "failed to probe for map_ram\n");
+ dev_err(&pdev->dev, "failed to probe for map_ram\n");
err = -ENOMEM;
goto exit_free;
}
@@ -237,27 +236,28 @@ static int platram_probe(struct device *dev)
#endif /* CONFIG_MTD_PARTITIONS */
if (add_mtd_device(info->mtd)) {
- dev_err(dev, "add_mtd_device() failed\n");
+ dev_err(&pdev->dev, "add_mtd_device() failed\n");
err = -ENOMEM;
}
- dev_info(dev, "registered mtd device\n");
+ dev_info(&pdev->dev, "registered mtd device\n");
return err;
exit_free:
- platram_remove(dev);
+ platram_remove(pdev);
exit_error:
return err;
}
/* device driver info */
-static struct device_driver platram_driver = {
- .name = "mtd-ram",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver platram_driver = {
.probe = platram_probe,
.remove = platram_remove,
+ .driver = {
+ .name = "mtd-ram",
+ .owner = THIS_MODULE,
+ },
};
/* module init/exit */
@@ -265,12 +265,12 @@ static struct device_driver platram_driver = {
static int __init platram_init(void)
{
printk("Generic platform RAM MTD, (c) 2004 Simtec Electronics\n");
- return driver_register(&platram_driver);
+ return platform_driver_register(&platram_driver);
}
static void __exit platram_exit(void)
{
- driver_unregister(&platram_driver);
+ platform_driver_unregister(&platram_driver);
}
module_init(platram_init);
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 9e8bb17..5cefb01 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -356,9 +356,8 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
-static int __init sa1100_mtd_probe(struct device *dev)
+static int __init sa1100_mtd_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct flash_platform_data *plat = pdev->dev.platform_data;
struct mtd_partition *parts;
const char *part_type = NULL;
@@ -402,28 +401,28 @@ static int __init sa1100_mtd_probe(struct device *dev)
info->nr_parts = nr_parts;
- dev_set_drvdata(dev, info);
+ platform_set_drvdata(pdev, info);
err = 0;
out:
return err;
}
-static int __exit sa1100_mtd_remove(struct device *dev)
+static int __exit sa1100_mtd_remove(struct platform_device *pdev)
{
- struct sa_info *info = dev_get_drvdata(dev);
- struct flash_platform_data *plat = dev->platform_data;
+ struct sa_info *info = platform_get_drvdata(pdev);
+ struct flash_platform_data *plat = pdev->dev.platform_data;
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
sa1100_destroy(info, plat);
return 0;
}
#ifdef CONFIG_PM
-static int sa1100_mtd_suspend(struct device *dev, pm_message_t state)
+static int sa1100_mtd_suspend(struct platform_device *dev, pm_message_t state)
{
- struct sa_info *info = dev_get_drvdata(dev);
+ struct sa_info *info = platform_get_drvdata(dev);
int ret = 0;
if (info)
@@ -432,17 +431,17 @@ static int sa1100_mtd_suspend(struct device *dev, pm_message_t state)
return ret;
}
-static int sa1100_mtd_resume(struct device *dev)
+static int sa1100_mtd_resume(struct platform_device *dev)
{
- struct sa_info *info = dev_get_drvdata(dev);
+ struct sa_info *info = platform_get_drvdata(dev);
if (info)
info->mtd->resume(info->mtd);
return 0;
}
-static void sa1100_mtd_shutdown(struct device *dev)
+static void sa1100_mtd_shutdown(struct platform_device *dev)
{
- struct sa_info *info = dev_get_drvdata(dev);
+ struct sa_info *info = platform_get_drvdata(dev);
if (info && info->mtd->suspend(info->mtd) == 0)
info->mtd->resume(info->mtd);
}
@@ -452,24 +451,25 @@ static void sa1100_mtd_shutdown(struct device *dev)
#define sa1100_mtd_shutdown NULL
#endif
-static struct device_driver sa1100_mtd_driver = {
- .name = "flash",
- .bus = &platform_bus_type,
+static struct platform_driver sa1100_mtd_driver = {
.probe = sa1100_mtd_probe,
.remove = __exit_p(sa1100_mtd_remove),
.suspend = sa1100_mtd_suspend,
.resume = sa1100_mtd_resume,
.shutdown = sa1100_mtd_shutdown,
+ .driver = {
+ .name = "flash",
+ },
};
static int __init sa1100_mtd_init(void)
{
- return driver_register(&sa1100_mtd_driver);
+ return platform_driver_register(&sa1100_mtd_driver);
}
static void __exit sa1100_mtd_exit(void)
{
- driver_unregister(&sa1100_mtd_driver);
+ platform_driver_unregister(&sa1100_mtd_driver);
}
module_init(sa1100_mtd_init);
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 97e9b78..d209214 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -125,14 +125,14 @@ static struct s3c2410_nand_info *s3c2410_nand_mtd_toinfo(struct mtd_info *mtd)
return s3c2410_nand_mtd_toours(mtd)->info;
}
-static struct s3c2410_nand_info *to_nand_info(struct device *dev)
+static struct s3c2410_nand_info *to_nand_info(struct platform_device *dev)
{
- return dev_get_drvdata(dev);
+ return platform_get_drvdata(dev);
}
-static struct s3c2410_platform_nand *to_nand_plat(struct device *dev)
+static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev)
{
- return dev->platform_data;
+ return dev->dev.platform_data;
}
/* timing calculations */
@@ -165,9 +165,9 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
/* controller setup */
static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
- struct device *dev)
+ struct platform_device *pdev)
{
- struct s3c2410_platform_nand *plat = to_nand_plat(dev);
+ struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
unsigned long clkrate = clk_get_rate(info->clk);
int tacls, twrph0, twrph1;
unsigned long cfg;
@@ -430,11 +430,11 @@ static void s3c2410_nand_write_buf(struct mtd_info *mtd,
/* device management functions */
-static int s3c2410_nand_remove(struct device *dev)
+static int s3c2410_nand_remove(struct platform_device *pdev)
{
- struct s3c2410_nand_info *info = to_nand_info(dev);
+ struct s3c2410_nand_info *info = to_nand_info(pdev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
if (info == NULL)
return 0;
@@ -562,10 +562,9 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
* nand layer to look for devices
*/
-static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
+static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct s3c2410_platform_nand *plat = to_nand_plat(dev);
+ struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
struct s3c2410_nand_info *info;
struct s3c2410_nand_mtd *nmtd;
struct s3c2410_nand_set *sets;
@@ -575,26 +574,26 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
int nr_sets;
int setno;
- pr_debug("s3c2410_nand_probe(%p)\n", dev);
+ pr_debug("s3c2410_nand_probe(%p)\n", pdev);
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (info == NULL) {
- dev_err(dev, "no memory for flash info\n");
+ dev_err(&pdev->dev, "no memory for flash info\n");
err = -ENOMEM;
goto exit_error;
}
memzero(info, sizeof(*info));
- dev_set_drvdata(dev, info);
+ platform_set_drvdata(pdev, info);
spin_lock_init(&info->controller.lock);
init_waitqueue_head(&info->controller.wq);
/* get the clock source and enable it */
- info->clk = clk_get(dev, "nand");
+ info->clk = clk_get(&pdev->dev, "nand");
if (IS_ERR(info->clk)) {
- dev_err(dev, "failed to get clock");
+ dev_err(&pdev->dev, "failed to get clock");
err = -ENOENT;
goto exit_error;
}
@@ -611,27 +610,27 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
info->area = request_mem_region(res->start, size, pdev->name);
if (info->area == NULL) {
- dev_err(dev, "cannot reserve register region\n");
+ dev_err(&pdev->dev, "cannot reserve register region\n");
err = -ENOENT;
goto exit_error;
}
- info->device = dev;
+ info->device = &pdev->dev;
info->platform = plat;
info->regs = ioremap(res->start, size);
info->is_s3c2440 = is_s3c2440;
if (info->regs == NULL) {
- dev_err(dev, "cannot reserve register region\n");
+ dev_err(&pdev->dev, "cannot reserve register region\n");
err = -EIO;
goto exit_error;
}
- dev_dbg(dev, "mapped registers at %p\n", info->regs);
+ dev_dbg(&pdev->dev, "mapped registers at %p\n", info->regs);
/* initialise the hardware */
- err = s3c2410_nand_inithw(info, dev);
+ err = s3c2410_nand_inithw(info, pdev);
if (err != 0)
goto exit_error;
@@ -645,7 +644,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
size = nr_sets * sizeof(*info->mtds);
info->mtds = kmalloc(size, GFP_KERNEL);
if (info->mtds == NULL) {
- dev_err(dev, "failed to allocate mtd storage\n");
+ dev_err(&pdev->dev, "failed to allocate mtd storage\n");
err = -ENOMEM;
goto exit_error;
}
@@ -677,7 +676,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
return 0;
exit_error:
- s3c2410_nand_remove(dev);
+ s3c2410_nand_remove(pdev);
if (err == 0)
err = -EINVAL;
@@ -686,44 +685,46 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
/* driver device registration */
-static int s3c2410_nand_probe(struct device *dev)
+static int s3c2410_nand_probe(struct platform_device *dev)
{
return s3c24xx_nand_probe(dev, 0);
}
-static int s3c2440_nand_probe(struct device *dev)
+static int s3c2440_nand_probe(struct platform_device *dev)
{
return s3c24xx_nand_probe(dev, 1);
}
-static struct device_driver s3c2410_nand_driver = {
- .name = "s3c2410-nand",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver s3c2410_nand_driver = {
.probe = s3c2410_nand_probe,
.remove = s3c2410_nand_remove,
+ .driver = {
+ .name = "s3c2410-nand",
+ .owner = THIS_MODULE,
+ },
};
-static struct device_driver s3c2440_nand_driver = {
- .name = "s3c2440-nand",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver s3c2440_nand_driver = {
.probe = s3c2440_nand_probe,
.remove = s3c2410_nand_remove,
+ .driver = {
+ .name = "s3c2440-nand",
+ .owner = THIS_MODULE,
+ },
};
static int __init s3c2410_nand_init(void)
{
printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");
- driver_register(&s3c2440_nand_driver);
- return driver_register(&s3c2410_nand_driver);
+ platform_driver_register(&s3c2440_nand_driver);
+ return platform_driver_register(&s3c2410_nand_driver);
}
static void __exit s3c2410_nand_exit(void)
{
- driver_unregister(&s3c2440_nand_driver);
- driver_unregister(&s3c2410_nand_driver);
+ platform_driver_unregister(&s3c2440_nand_driver);
+ platform_driver_unregister(&s3c2410_nand_driver);
}
module_init(s3c2410_nand_init);
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 977935a..824e430 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -84,6 +84,7 @@ static int max_interrupt_work = 10;
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/pm.h>
+#include <linux/pm_legacy.h>
#include <linux/skbuff.h>
#include <linux/delay.h> /* for udelay() */
#include <linux/spinlock.h>
@@ -173,7 +174,7 @@ struct el3_private {
/* skb send-queue */
int head, size;
struct sk_buff *queue[SKB_QUEUE_SIZE];
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
struct pm_dev *pmdev;
#endif
enum {
@@ -200,7 +201,7 @@ static void el3_tx_timeout (struct net_device *dev);
static void el3_down(struct net_device *dev);
static void el3_up(struct net_device *dev);
static struct ethtool_ops ethtool_ops;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
static int el3_suspend(struct pm_dev *pdev);
static int el3_resume(struct pm_dev *pdev);
static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data);
@@ -361,7 +362,7 @@ static void el3_common_remove (struct net_device *dev)
struct el3_private *lp = netdev_priv(dev);
(void) lp; /* Keep gcc quiet... */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
if (lp->pmdev)
pm_unregister(lp->pmdev);
#endif
@@ -571,7 +572,7 @@ no_pnp:
if (err)
goto out1;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
/* register power management */
lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
if (lp->pmdev) {
@@ -1479,7 +1480,7 @@ el3_up(struct net_device *dev)
}
/* Power Management support functions */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
static int
el3_suspend(struct pm_dev *pdev)
@@ -1548,7 +1549,7 @@ el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data)
return 0;
}
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_LEGACY */
/* Parameters that may be passed into the module. */
static int debug = -1;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 5c69d57..ebd7313 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -812,7 +812,7 @@ config SMC91X
tristate "SMC 91C9x/91C1xxx support"
select CRC32
select MII
- depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH)
+ depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00)
help
This is a driver for SMC's 91x series of Ethernet chipsets,
including the SMC91C94 and the SMC91C111. Say Y if you want it
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 332e995..cd0b1dc 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -32,6 +32,7 @@
*
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 8f46427..49fa1e4 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -2707,7 +2707,7 @@ bnx2_init_nvram(struct bnx2 *bp)
if (j == entry_count) {
bp->flash_info = NULL;
- printk(KERN_ALERT "Unknown flash/EEPROM type.\n");
+ printk(KERN_ALERT PFX "Unknown flash/EEPROM type.\n");
rc = -ENODEV;
}
@@ -3903,6 +3903,8 @@ bnx2_test_loopback(struct bnx2 *bp)
pkt_size = 1514;
skb = dev_alloc_skb(pkt_size);
+ if (!skb)
+ return -ENOMEM;
packet = skb_put(skb, pkt_size);
memcpy(packet, bp->mac_addr, 6);
memset(packet + 6, 0x0, 8);
@@ -4798,11 +4800,7 @@ bnx2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
struct bnx2 *bp = dev->priv;
int rc;
- if (eeprom->offset > bp->flash_info->total_size)
- return -EINVAL;
-
- if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
- eeprom->len = bp->flash_info->total_size - eeprom->offset;
+ /* parameters already validated in ethtool_get_eeprom */
rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
@@ -4816,11 +4814,7 @@ bnx2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
struct bnx2 *bp = dev->priv;
int rc;
- if (eeprom->offset > bp->flash_info->total_size)
- return -EINVAL;
-
- if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
- eeprom->len = bp->flash_info->total_size - eeprom->offset;
+ /* parameters already validated in ethtool_set_eeprom */
rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 0d33a93..03804cc 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -398,13 +398,19 @@ static struct mca_driver depca_mca_driver = {
};
#endif
-static int depca_isa_probe (struct device *);
+static int depca_isa_probe (struct platform_device *);
-static struct device_driver depca_isa_driver = {
- .name = depca_string,
- .bus = &platform_bus_type,
+static int __devexit depca_isa_remove(struct platform_device *pdev)
+{
+ return depca_device_remove(&pdev->dev);
+}
+
+static struct platform_driver depca_isa_driver = {
.probe = depca_isa_probe,
- .remove = __devexit_p(depca_device_remove),
+ .remove = __devexit_p(depca_isa_remove),
+ .driver = {
+ .name = depca_string,
+ },
};
/*
@@ -1525,7 +1531,7 @@ static enum depca_type __init depca_shmem_probe (ulong *mem_start)
return adapter;
}
-static int __init depca_isa_probe (struct device *device)
+static int __init depca_isa_probe (struct platform_device *device)
{
struct net_device *dev;
struct depca_private *lp;
@@ -1533,7 +1539,7 @@ static int __init depca_isa_probe (struct device *device)
enum depca_type adapter = unknown;
int status = 0;
- ioaddr = (u_long) device->platform_data;
+ ioaddr = (u_long) device->dev.platform_data;
if ((status = depca_common_init (ioaddr, &dev)))
goto out;
@@ -1553,7 +1559,7 @@ static int __init depca_isa_probe (struct device *device)
lp->adapter = adapter;
lp->mem_start = mem_start;
- if ((status = depca_hw_init(dev, device)))
+ if ((status = depca_hw_init(dev, &device->dev)))
goto out_free;
return 0;
@@ -2082,7 +2088,7 @@ static int __init depca_module_init (void)
#ifdef CONFIG_EISA
err |= eisa_driver_register (&depca_eisa_driver);
#endif
- err |= driver_register (&depca_isa_driver);
+ err |= platform_driver_register (&depca_isa_driver);
depca_platform_probe ();
return err;
@@ -2097,7 +2103,7 @@ static void __exit depca_module_exit (void)
#ifdef CONFIG_EISA
eisa_driver_unregister (&depca_eisa_driver);
#endif
- driver_unregister (&depca_isa_driver);
+ platform_driver_unregister (&depca_isa_driver);
for (i = 0; depca_io_ports[i].iobase; i++) {
if (depca_io_ports[i].device) {
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index f8c9bcd..24996da 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -148,7 +148,7 @@ typedef struct board_info {
} board_info_t;
/* function declaration ------------------------------------- */
-static int dm9000_probe(struct device *);
+static int dm9000_probe(struct platform_device *);
static int dm9000_open(struct net_device *);
static int dm9000_start_xmit(struct sk_buff *, struct net_device *);
static int dm9000_stop(struct net_device *);
@@ -378,9 +378,8 @@ dm9000_release_board(struct platform_device *pdev, struct board_info *db)
* Search DM9000 board, allocate space and register it
*/
static int
-dm9000_probe(struct device *dev)
+dm9000_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct dm9000_plat_data *pdata = pdev->dev.platform_data;
struct board_info *db; /* Point a board information structure */
struct net_device *ndev;
@@ -398,7 +397,7 @@ dm9000_probe(struct device *dev)
}
SET_MODULE_OWNER(ndev);
- SET_NETDEV_DEV(ndev, dev);
+ SET_NETDEV_DEV(ndev, &pdev->dev);
PRINTK2("dm9000_probe()");
@@ -569,7 +568,7 @@ dm9000_probe(struct device *dev)
printk("%s: Invalid ethernet MAC address. Please "
"set using ifconfig\n", ndev->name);
- dev_set_drvdata(dev, ndev);
+ platform_set_drvdata(pdev, ndev);
ret = register_netdev(ndev);
if (ret == 0) {
@@ -1140,9 +1139,9 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
}
static int
-dm9000_drv_suspend(struct device *dev, pm_message_t state)
+dm9000_drv_suspend(struct platform_device *dev, pm_message_t state)
{
- struct net_device *ndev = dev_get_drvdata(dev);
+ struct net_device *ndev = platform_get_drvdata(dev);
if (ndev) {
if (netif_running(ndev)) {
@@ -1154,9 +1153,9 @@ dm9000_drv_suspend(struct device *dev, pm_message_t state)
}
static int
-dm9000_drv_resume(struct device *dev)
+dm9000_drv_resume(struct platform_device *dev)
{
- struct net_device *ndev = dev_get_drvdata(dev);
+ struct net_device *ndev = platform_get_drvdata(dev);
board_info_t *db = (board_info_t *) ndev->priv;
if (ndev) {
@@ -1172,12 +1171,11 @@ dm9000_drv_resume(struct device *dev)
}
static int
-dm9000_drv_remove(struct device *dev)
+dm9000_drv_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct net_device *ndev = dev_get_drvdata(dev);
+ struct net_device *ndev = platform_get_drvdata(pdev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
unregister_netdev(ndev);
dm9000_release_board(pdev, (board_info_t *) ndev->priv);
@@ -1188,13 +1186,14 @@ dm9000_drv_remove(struct device *dev)
return 0;
}
-static struct device_driver dm9000_driver = {
- .name = "dm9000",
- .bus = &platform_bus_type,
+static struct platform_driver dm9000_driver = {
.probe = dm9000_probe,
.remove = dm9000_drv_remove,
.suspend = dm9000_drv_suspend,
.resume = dm9000_drv_resume,
+ .driver = {
+ .name = "dm9000",
+ },
};
static int __init
@@ -1202,13 +1201,13 @@ dm9000_init(void)
{
printk(KERN_INFO "%s Ethernet Driver\n", CARDNAME);
- return driver_register(&dm9000_driver); /* search board and register */
+ return platform_driver_register(&dm9000_driver); /* search board and register */
}
static void __exit
dm9000_cleanup(void)
{
- driver_unregister(&dm9000_driver);
+ platform_driver_unregister(&dm9000_driver);
}
module_init(dm9000_init);
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 7a6aeae..22cd045 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -156,7 +156,7 @@
#define DRV_NAME "e100"
#define DRV_EXT "-NAPI"
-#define DRV_VERSION "3.4.14-k2"DRV_EXT
+#define DRV_VERSION "3.4.14-k4"DRV_EXT
#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation"
#define PFX DRV_NAME ": "
@@ -903,8 +903,8 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
static void e100_get_defaults(struct nic *nic)
{
- struct param_range rfds = { .min = 16, .max = 256, .count = 64 };
- struct param_range cbs = { .min = 64, .max = 256, .count = 64 };
+ struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
+ struct param_range cbs = { .min = 64, .max = 256, .count = 128 };
pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
/* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
@@ -1007,25 +1007,264 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
}
+/********************************************************/
+/* Micro code for 8086:1229 Rev 8 */
+/********************************************************/
+
+/* Parameter values for the D101M B-step */
+#define D101M_CPUSAVER_TIMER_DWORD 78
+#define D101M_CPUSAVER_BUNDLE_DWORD 65
+#define D101M_CPUSAVER_MIN_SIZE_DWORD 126
+
+#define D101M_B_RCVBUNDLE_UCODE \
+{\
+0x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \
+0x000C0001, 0x00101312, 0x000C0008, 0x00380216, \
+0x0010009C, 0x00204056, 0x002380CC, 0x00380056, \
+0x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \
+0x00380438, 0x00000000, 0x00140000, 0x00380555, \
+0x00308000, 0x00100662, 0x00100561, 0x000E0408, \
+0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
+0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
+0x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \
+0x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \
+0x003A0437, 0x00044010, 0x0038078A, 0x00000000, \
+0x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \
+0x00130824, 0x000C0001, 0x00101213, 0x00260C75, \
+0x00041000, 0x00010004, 0x00130826, 0x000C0006, \
+0x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
+0x00101210, 0x00380C34, 0x00000000, 0x00000000, \
+0x0021155B, 0x00100099, 0x00206559, 0x0010009C, \
+0x00244559, 0x00130836, 0x000C0000, 0x00220C62, \
+0x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \
+0x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \
+0x00214C0E, 0x00380555, 0x00010004, 0x00041000, \
+0x00278C67, 0x00040800, 0x00018100, 0x003A0437, \
+0x00130826, 0x000C0001, 0x00220559, 0x00101313, \
+0x00380559, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00130831, 0x0010090B, 0x00124813, \
+0x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \
+0x003806A8, 0x00000000, 0x00000000, 0x00000000, \
+}
+
+/********************************************************/
+/* Micro code for 8086:1229 Rev 9 */
+/********************************************************/
+
+/* Parameter values for the D101S */
+#define D101S_CPUSAVER_TIMER_DWORD 78
+#define D101S_CPUSAVER_BUNDLE_DWORD 67
+#define D101S_CPUSAVER_MIN_SIZE_DWORD 128
+
+#define D101S_RCVBUNDLE_UCODE \
+{\
+0x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \
+0x000C0001, 0x00101312, 0x000C0008, 0x00380243, \
+0x0010009C, 0x00204056, 0x002380D0, 0x00380056, \
+0x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \
+0x0038047F, 0x00000000, 0x00140000, 0x003805A3, \
+0x00308000, 0x00100610, 0x00100561, 0x000E0408, \
+0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
+0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
+0x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \
+0x00380F90, 0x00080000, 0x00103090, 0x00380F90, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \
+0x003A047E, 0x00044010, 0x00380819, 0x00000000, \
+0x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \
+0x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \
+0x00101213, 0x00260FF7, 0x00041000, 0x00010004, \
+0x00130826, 0x000C0006, 0x00220700, 0x0013C926, \
+0x00101313, 0x00380700, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
+0x00101210, 0x00380FB6, 0x00000000, 0x00000000, \
+0x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \
+0x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \
+0x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \
+0x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \
+0x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \
+0x00010004, 0x00041000, 0x00278FE9, 0x00040800, \
+0x00018100, 0x003A047E, 0x00130826, 0x000C0001, \
+0x002205A7, 0x00101313, 0x003805A7, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00130831, \
+0x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \
+0x00041000, 0x00010004, 0x00380700 \
+}
+
+/********************************************************/
+/* Micro code for the 8086:1229 Rev F/10 */
+/********************************************************/
+
+/* Parameter values for the D102 E-step */
+#define D102_E_CPUSAVER_TIMER_DWORD 42
+#define D102_E_CPUSAVER_BUNDLE_DWORD 54
+#define D102_E_CPUSAVER_MIN_SIZE_DWORD 46
+
+#define D102_E_RCVBUNDLE_UCODE \
+{\
+0x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \
+0x00E014B9, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014BD, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014D5, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014C1, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014C8, 0x00000000, 0x00000000, 0x00000000, \
+0x00200600, 0x00E014EE, 0x00000000, 0x00000000, \
+0x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \
+0x00E00E43, 0x00000000, 0x00000000, 0x00000000, \
+0x00300006, 0x00E014FB, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \
+0x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+}
+
static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
{
- int i;
- static const u32 ucode[UCODE_SIZE] = {
- /* NFS packets are misinterpreted as TCO packets and
- * incorrectly routed to the BMC over SMBus. This
- * microcode patch checks the fragmented IP bit in the
- * NFS/UDP header to distinguish between NFS and TCO. */
- 0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF,
- 0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000,
- 0x00906EFD, 0x00900EFD, 0x00E00EF8,
- };
-
- if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) {
- for(i = 0; i < UCODE_SIZE; i++)
+/* *INDENT-OFF* */
+ static struct {
+ u32 ucode[UCODE_SIZE + 1];
+ u8 mac;
+ u8 timer_dword;
+ u8 bundle_dword;
+ u8 min_size_dword;
+ } ucode_opts[] = {
+ { D101M_B_RCVBUNDLE_UCODE,
+ mac_82559_D101M,
+ D101M_CPUSAVER_TIMER_DWORD,
+ D101M_CPUSAVER_BUNDLE_DWORD,
+ D101M_CPUSAVER_MIN_SIZE_DWORD },
+ { D101S_RCVBUNDLE_UCODE,
+ mac_82559_D101S,
+ D101S_CPUSAVER_TIMER_DWORD,
+ D101S_CPUSAVER_BUNDLE_DWORD,
+ D101S_CPUSAVER_MIN_SIZE_DWORD },
+ { D102_E_RCVBUNDLE_UCODE,
+ mac_82551_F,
+ D102_E_CPUSAVER_TIMER_DWORD,
+ D102_E_CPUSAVER_BUNDLE_DWORD,
+ D102_E_CPUSAVER_MIN_SIZE_DWORD },
+ { D102_E_RCVBUNDLE_UCODE,
+ mac_82551_10,
+ D102_E_CPUSAVER_TIMER_DWORD,
+ D102_E_CPUSAVER_BUNDLE_DWORD,
+ D102_E_CPUSAVER_MIN_SIZE_DWORD },
+ { {0}, 0, 0, 0, 0}
+ }, *opts;
+/* *INDENT-ON* */
+
+/*************************************************************************
+* CPUSaver parameters
+*
+* All CPUSaver parameters are 16-bit literals that are part of a
+* "move immediate value" instruction. By changing the value of
+* the literal in the instruction before the code is loaded, the
+* driver can change the algorithm.
+*
+* INTDELAY - This loads the dead-man timer with its inital value.
+* When this timer expires the interrupt is asserted, and the
+* timer is reset each time a new packet is received. (see
+* BUNDLEMAX below to set the limit on number of chained packets)
+* The current default is 0x600 or 1536. Experiments show that
+* the value should probably stay within the 0x200 - 0x1000.
+*
+* BUNDLEMAX -
+* This sets the maximum number of frames that will be bundled. In
+* some situations, such as the TCP windowing algorithm, it may be
+* better to limit the growth of the bundle size than let it go as
+* high as it can, because that could cause too much added latency.
+* The default is six, because this is the number of packets in the
+* default TCP window size. A value of 1 would make CPUSaver indicate
+* an interrupt for every frame received. If you do not want to put
+* a limit on the bundle size, set this value to xFFFF.
+*
+* BUNDLESMALL -
+* This contains a bit-mask describing the minimum size frame that
+* will be bundled. The default masks the lower 7 bits, which means
+* that any frame less than 128 bytes in length will not be bundled,
+* but will instead immediately generate an interrupt. This does
+* not affect the current bundle in any way. Any frame that is 128
+* bytes or large will be bundled normally. This feature is meant
+* to provide immediate indication of ACK frames in a TCP environment.
+* Customers were seeing poor performance when a machine with CPUSaver
+* enabled was sending but not receiving. The delay introduced when
+* the ACKs were received was enough to reduce total throughput, because
+* the sender would sit idle until the ACK was finally seen.
+*
+* The current default is 0xFF80, which masks out the lower 7 bits.
+* This means that any frame which is x7F (127) bytes or smaller
+* will cause an immediate interrupt. Because this value must be a
+* bit mask, there are only a few valid values that can be used. To
+* turn this feature off, the driver can write the value xFFFF to the
+* lower word of this instruction (in the same way that the other
+* parameters are used). Likewise, a value of 0xF800 (2047) would
+* cause an interrupt to be generated for every frame, because all
+* standard Ethernet frames are <= 2047 bytes in length.
+*************************************************************************/
+
+/* if you wish to disable the ucode functionality, while maintaining the
+ * workarounds it provides, set the following defines to:
+ * BUNDLESMALL 0
+ * BUNDLEMAX 1
+ * INTDELAY 1
+ */
+#define BUNDLESMALL 1
+#define BUNDLEMAX (u16)6
+#define INTDELAY (u16)1536 /* 0x600 */
+
+ /* do not load u-code for ICH devices */
+ if (nic->flags & ich)
+ goto noloaducode;
+
+ /* Search for ucode match against h/w rev_id */
+ for (opts = ucode_opts; opts->mac; opts++) {
+ int i;
+ u32 *ucode = opts->ucode;
+ if (nic->mac != opts->mac)
+ continue;
+
+ /* Insert user-tunable settings */
+ ucode[opts->timer_dword] &= 0xFFFF0000;
+ ucode[opts->timer_dword] |= INTDELAY;
+ ucode[opts->bundle_dword] &= 0xFFFF0000;
+ ucode[opts->bundle_dword] |= BUNDLEMAX;
+ ucode[opts->min_size_dword] &= 0xFFFF0000;
+ ucode[opts->min_size_dword] |= (BUNDLESMALL) ? 0xFFFF : 0xFF80;
+
+ for (i = 0; i < UCODE_SIZE; i++)
cb->u.ucode[i] = cpu_to_le32(ucode[i]);
cb->command = cpu_to_le16(cb_ucode);
- } else
- cb->command = cpu_to_le16(cb_nop);
+ return;
+ }
+
+noloaducode:
+ cb->command = cpu_to_le16(cb_nop);
}
static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig
index 94e7a9a..a84c232 100644
--- a/drivers/net/fec_8xx/Kconfig
+++ b/drivers/net/fec_8xx/Kconfig
@@ -1,6 +1,6 @@
config FEC_8XX
tristate "Motorola 8xx FEC driver"
- depends on NET_ETHERNET && FEC
+ depends on NET_ETHERNET && 8xx
select MII
config FEC_8XX_GENERIC_PHY
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 22aec6e..525624f 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -80,7 +80,7 @@
* into nv_close, otherwise reenabling for wol can
* cause DMA to kfree'd memory.
* 0.31: 14 Nov 2004: ethtool support for getting/setting link
- * capabilities.
+ * capabilities.
* 0.32: 16 Apr 2005: RX_ERROR4 handling added.
* 0.33: 16 May 2005: Support for MCP51 added.
* 0.34: 18 Jun 2005: Add DEV_NEED_LINKTIMER to all nForce nics.
@@ -89,14 +89,17 @@
* 0.37: 10 Jul 2005: Additional ethtool support, cleanup of pci id list
* 0.38: 16 Jul 2005: tx irq rewrite: Use global flags instead of
* per-packet flags.
- * 0.39: 18 Jul 2005: Add 64bit descriptor support.
- * 0.40: 19 Jul 2005: Add support for mac address change.
- * 0.41: 30 Jul 2005: Write back original MAC in nv_close instead
+ * 0.39: 18 Jul 2005: Add 64bit descriptor support.
+ * 0.40: 19 Jul 2005: Add support for mac address change.
+ * 0.41: 30 Jul 2005: Write back original MAC in nv_close instead
* of nv_remove
- * 0.42: 06 Aug 2005: Fix lack of link speed initialization
+ * 0.42: 06 Aug 2005: Fix lack of link speed initialization
* in the second (and later) nv_open call
- * 0.43: 10 Aug 2005: Add support for tx checksum.
- * 0.44: 20 Aug 2005: Add support for scatter gather and segmentation.
+ * 0.43: 10 Aug 2005: Add support for tx checksum.
+ * 0.44: 20 Aug 2005: Add support for scatter gather and segmentation.
+ * 0.45: 18 Sep 2005: Remove nv_stop/start_rx from every link check
+ * 0.46: 20 Oct 2005: Add irq optimization modes.
+ * 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan.
*
* Known bugs:
* We suspect that on some hardware no TX done interrupts are generated.
@@ -108,7 +111,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic.
*/
-#define FORCEDETH_VERSION "0.44"
+#define FORCEDETH_VERSION "0.47"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
@@ -163,7 +166,8 @@ enum {
#define NVREG_IRQ_LINK 0x0040
#define NVREG_IRQ_TX_ERROR 0x0080
#define NVREG_IRQ_TX1 0x0100
-#define NVREG_IRQMASK_WANTED 0x00df
+#define NVREG_IRQMASK_THROUGHPUT 0x00df
+#define NVREG_IRQMASK_CPU 0x0040
#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \
NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX_ERROR| \
@@ -177,7 +181,8 @@ enum {
* NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
*/
NvRegPollingInterval = 0x00c,
-#define NVREG_POLL_DEFAULT 970
+#define NVREG_POLL_DEFAULT_THROUGHPUT 970
+#define NVREG_POLL_DEFAULT_CPU 13
NvRegMisc1 = 0x080,
#define NVREG_MISC1_HD 0x02
#define NVREG_MISC1_FORCE 0x3b0f3c
@@ -538,6 +543,25 @@ struct fe_priv {
*/
static int max_interrupt_work = 5;
+/*
+ * Optimization can be either throuput mode or cpu mode
+ *
+ * Throughput Mode: Every tx and rx packet will generate an interrupt.
+ * CPU Mode: Interrupts are controlled by a timer.
+ */
+#define NV_OPTIMIZATION_MODE_THROUGHPUT 0
+#define NV_OPTIMIZATION_MODE_CPU 1
+static int optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT;
+
+/*
+ * Poll interval for timer irq
+ *
+ * This interval determines how frequent an interrupt is generated.
+ * The is value is determined by [(time_in_micro_secs * 100) / (2^10)]
+ * Min = 0, and Max = 65535
+ */
+static int poll_interval = -1;
+
static inline struct fe_priv *get_nvpriv(struct net_device *dev)
{
return netdev_priv(dev);
@@ -1328,67 +1352,71 @@ static void nv_rx_process(struct net_device *dev)
if (!(Flags & NV_RX_DESCRIPTORVALID))
goto next_pkt;
- if (Flags & NV_RX_MISSEDFRAME) {
- np->stats.rx_missed_errors++;
- np->stats.rx_errors++;
- goto next_pkt;
- }
- if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) {
- np->stats.rx_errors++;
- goto next_pkt;
- }
- if (Flags & NV_RX_CRCERR) {
- np->stats.rx_crc_errors++;
- np->stats.rx_errors++;
- goto next_pkt;
- }
- if (Flags & NV_RX_OVERFLOW) {
- np->stats.rx_over_errors++;
- np->stats.rx_errors++;
- goto next_pkt;
- }
- if (Flags & NV_RX_ERROR4) {
- len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
- if (len < 0) {
+ if (Flags & NV_RX_ERROR) {
+ if (Flags & NV_RX_MISSEDFRAME) {
+ np->stats.rx_missed_errors++;
np->stats.rx_errors++;
goto next_pkt;
}
- }
- /* framing errors are soft errors. */
- if (Flags & NV_RX_FRAMINGERR) {
- if (Flags & NV_RX_SUBSTRACT1) {
- len--;
+ if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) {
+ np->stats.rx_errors++;
+ goto next_pkt;
+ }
+ if (Flags & NV_RX_CRCERR) {
+ np->stats.rx_crc_errors++;
+ np->stats.rx_errors++;
+ goto next_pkt;
+ }
+ if (Flags & NV_RX_OVERFLOW) {
+ np->stats.rx_over_errors++;
+ np->stats.rx_errors++;
+ goto next_pkt;
+ }
+ if (Flags & NV_RX_ERROR4) {
+ len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
+ if (len < 0) {
+ np->stats.rx_errors++;
+ goto next_pkt;
+ }
+ }
+ /* framing errors are soft errors. */
+ if (Flags & NV_RX_FRAMINGERR) {
+ if (Flags & NV_RX_SUBSTRACT1) {
+ len--;
+ }
}
}
} else {
if (!(Flags & NV_RX2_DESCRIPTORVALID))
goto next_pkt;
- if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) {
- np->stats.rx_errors++;
- goto next_pkt;
- }
- if (Flags & NV_RX2_CRCERR) {
- np->stats.rx_crc_errors++;
- np->stats.rx_errors++;
- goto next_pkt;
- }
- if (Flags & NV_RX2_OVERFLOW) {
- np->stats.rx_over_errors++;
- np->stats.rx_errors++;
- goto next_pkt;
- }
- if (Flags & NV_RX2_ERROR4) {
- len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
- if (len < 0) {
+ if (Flags & NV_RX2_ERROR) {
+ if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) {
np->stats.rx_errors++;
goto next_pkt;
}
- }
- /* framing errors are soft errors */
- if (Flags & NV_RX2_FRAMINGERR) {
- if (Flags & NV_RX2_SUBSTRACT1) {
- len--;
+ if (Flags & NV_RX2_CRCERR) {
+ np->stats.rx_crc_errors++;
+ np->stats.rx_errors++;
+ goto next_pkt;
+ }
+ if (Flags & NV_RX2_OVERFLOW) {
+ np->stats.rx_over_errors++;
+ np->stats.rx_errors++;
+ goto next_pkt;
+ }
+ if (Flags & NV_RX2_ERROR4) {
+ len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
+ if (len < 0) {
+ np->stats.rx_errors++;
+ goto next_pkt;
+ }
+ }
+ /* framing errors are soft errors */
+ if (Flags & NV_RX2_FRAMINGERR) {
+ if (Flags & NV_RX2_SUBSTRACT1) {
+ len--;
+ }
}
}
Flags &= NV_RX2_CHECKSUMMASK;
@@ -1612,6 +1640,17 @@ static void nv_set_multicast(struct net_device *dev)
spin_unlock_irq(&np->lock);
}
+/**
+ * nv_update_linkspeed: Setup the MAC according to the link partner
+ * @dev: Network device to be configured
+ *
+ * The function queries the PHY and checks if there is a link partner.
+ * If yes, then it sets up the MAC accordingly. Otherwise, the MAC is
+ * set to 10 MBit HD.
+ *
+ * The function returns 0 if there is no link partner and 1 if there is
+ * a good link partner.
+ */
static int nv_update_linkspeed(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
@@ -1751,13 +1790,11 @@ set_speed:
static void nv_linkchange(struct net_device *dev)
{
if (nv_update_linkspeed(dev)) {
- if (netif_carrier_ok(dev)) {
- nv_stop_rx(dev);
- } else {
+ if (!netif_carrier_ok(dev)) {
netif_carrier_on(dev);
printk(KERN_INFO "%s: link up.\n", dev->name);
+ nv_start_rx(dev);
}
- nv_start_rx(dev);
} else {
if (netif_carrier_ok(dev)) {
netif_carrier_off(dev);
@@ -1799,22 +1836,18 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
if (!(events & np->irqmask))
break;
- if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_ERROR|NVREG_IRQ_TX_ERR)) {
+ spin_lock(&np->lock);
+ nv_tx_done(dev);
+ spin_unlock(&np->lock);
+
+ nv_rx_process(dev);
+ if (nv_alloc_rx(dev)) {
spin_lock(&np->lock);
- nv_tx_done(dev);
+ if (!np->in_shutdown)
+ mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
spin_unlock(&np->lock);
}
-
- if (events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) {
- nv_rx_process(dev);
- if (nv_alloc_rx(dev)) {
- spin_lock(&np->lock);
- if (!np->in_shutdown)
- mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
- spin_unlock(&np->lock);
- }
- }
-
+
if (events & NVREG_IRQ_LINK) {
spin_lock(&np->lock);
nv_link_irq(dev);
@@ -2216,7 +2249,14 @@ static int nv_open(struct net_device *dev)
writel(NVREG_RNDSEED_FORCE | (i&NVREG_RNDSEED_MASK), base + NvRegRandomSeed);
writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1);
writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2);
- writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval);
+ if (poll_interval == -1) {
+ if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT)
+ writel(NVREG_POLL_DEFAULT_THROUGHPUT, base + NvRegPollingInterval);
+ else
+ writel(NVREG_POLL_DEFAULT_CPU, base + NvRegPollingInterval);
+ }
+ else
+ writel(poll_interval & 0xFFFF, base + NvRegPollingInterval);
writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);
writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID|NVREG_ADAPTCTL_RUNNING,
base + NvRegAdapterControl);
@@ -2501,7 +2541,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
} else {
np->tx_flags = NV_TX2_VALID;
}
- np->irqmask = NVREG_IRQMASK_WANTED;
+ if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT)
+ np->irqmask = NVREG_IRQMASK_THROUGHPUT;
+ else
+ np->irqmask = NVREG_IRQMASK_CPU;
+
if (id->driver_data & DEV_NEED_TIMERIRQ)
np->irqmask |= NVREG_IRQ_TIMER;
if (id->driver_data & DEV_NEED_LINKTIMER) {
@@ -2514,16 +2558,17 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
}
/* find a suitable phy */
- for (i = 1; i < 32; i++) {
+ for (i = 1; i <= 32; i++) {
int id1, id2;
+ int phyaddr = i & 0x1F;
spin_lock_irq(&np->lock);
- id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ);
+ id1 = mii_rw(dev, phyaddr, MII_PHYSID1, MII_READ);
spin_unlock_irq(&np->lock);
if (id1 < 0 || id1 == 0xffff)
continue;
spin_lock_irq(&np->lock);
- id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ);
+ id2 = mii_rw(dev, phyaddr, MII_PHYSID2, MII_READ);
spin_unlock_irq(&np->lock);
if (id2 < 0 || id2 == 0xffff)
continue;
@@ -2531,23 +2576,19 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT;
id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT;
dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n",
- pci_name(pci_dev), id1, id2, i);
- np->phyaddr = i;
+ pci_name(pci_dev), id1, id2, phyaddr);
+ np->phyaddr = phyaddr;
np->phy_oui = id1 | id2;
break;
}
- if (i == 32) {
- /* PHY in isolate mode? No phy attached and user wants to
- * test loopback? Very odd, but can be correct.
- */
+ if (i == 33) {
printk(KERN_INFO "%s: open: Could not find a valid PHY.\n",
- pci_name(pci_dev));
- }
-
- if (i != 32) {
- /* reset it */
- phy_init(dev);
+ pci_name(pci_dev));
+ goto out_freering;
}
+
+ /* reset it */
+ phy_init(dev);
/* set default link speed settings */
np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
@@ -2689,6 +2730,10 @@ static void __exit exit_nic(void)
module_param(max_interrupt_work, int, 0);
MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt");
+module_param(optimization_mode, int, 0);
+MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer.");
+module_param(poll_interval, int, 0);
+MODULE_PARM_DESC(poll_interval, "Interval determines how frequent timer interrupt is generated by [(time_in_micro_secs * 100) / (2^10)]. Min is 0 and Max is 65535.");
MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 54d294a..0f030b7 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -6,7 +6,7 @@
* Based on 8260_io/fcc_enet.c
*
* Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ * Maintainer: Kumar Gala
*
* Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
*
@@ -126,8 +126,8 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static void adjust_link(struct net_device *dev);
static void init_registers(struct net_device *dev);
static int init_phy(struct net_device *dev);
-static int gfar_probe(struct device *device);
-static int gfar_remove(struct device *device);
+static int gfar_probe(struct platform_device *pdev);
+static int gfar_remove(struct platform_device *pdev);
static void free_skb_resources(struct gfar_private *priv);
static void gfar_set_multi(struct net_device *dev);
static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
@@ -156,12 +156,11 @@ int gfar_uses_fcb(struct gfar_private *priv)
/* Set up the ethernet device structure, private data,
* and anything else we need before we start */
-static int gfar_probe(struct device *device)
+static int gfar_probe(struct platform_device *pdev)
{
u32 tempval;
struct net_device *dev = NULL;
struct gfar_private *priv = NULL;
- struct platform_device *pdev = to_platform_device(device);
struct gianfar_platform_data *einfo;
struct resource *r;
int idx;
@@ -208,7 +207,7 @@ static int gfar_probe(struct device *device)
spin_lock_init(&priv->lock);
- dev_set_drvdata(device, dev);
+ platform_set_drvdata(pdev, dev);
/* Stop the DMA engine now, in case it was running before */
/* (The firmware could have used it, and left it running). */
@@ -245,7 +244,7 @@ static int gfar_probe(struct device *device)
dev->base_addr = (unsigned long) (priv->regs);
SET_MODULE_OWNER(dev);
- SET_NETDEV_DEV(dev, device);
+ SET_NETDEV_DEV(dev, &pdev->dev);
/* Fill in the dev structure */
dev->open = gfar_enet_open;
@@ -377,12 +376,12 @@ regs_fail:
return err;
}
-static int gfar_remove(struct device *device)
+static int gfar_remove(struct platform_device *pdev)
{
- struct net_device *dev = dev_get_drvdata(device);
+ struct net_device *dev = platform_get_drvdata(pdev);
struct gfar_private *priv = netdev_priv(dev);
- dev_set_drvdata(device, NULL);
+ platform_set_drvdata(pdev, NULL);
iounmap((void *) priv->regs);
free_netdev(dev);
@@ -1861,11 +1860,12 @@ static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs)
}
/* Structure for a device driver */
-static struct device_driver gfar_driver = {
- .name = "fsl-gianfar",
- .bus = &platform_bus_type,
+static struct platform_driver gfar_driver = {
.probe = gfar_probe,
.remove = gfar_remove,
+ .driver = {
+ .name = "fsl-gianfar",
+ },
};
static int __init gfar_init(void)
@@ -1875,7 +1875,7 @@ static int __init gfar_init(void)
if (err)
return err;
- err = driver_register(&gfar_driver);
+ err = platform_driver_register(&gfar_driver);
if (err)
gfar_mdio_exit();
@@ -1885,7 +1885,7 @@ static int __init gfar_init(void)
static void __exit gfar_exit(void)
{
- driver_unregister(&gfar_driver);
+ platform_driver_unregister(&gfar_driver);
gfar_mdio_exit();
}
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 220084e..5065ba8 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -6,7 +6,7 @@
* Based on 8260_io/fcc_enet.c
*
* Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ * Maintainer: Kumar Gala
*
* Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
*
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 5a2d810..cfa3cd7 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -6,7 +6,7 @@
* Based on e1000 ethtool support
*
* Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ * Maintainer: Kumar Gala
*
* Copyright (c) 2003,2004 Freescale Semiconductor, Inc.
*
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 7263395..04a462c 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -5,7 +5,7 @@
* Provides Bus interface for MIIM regs
*
* Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ * Maintainer: Kumar Gala
*
* Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
*
@@ -133,7 +133,7 @@ int gfar_mdio_probe(struct device *dev)
if (NULL == dev)
return -EINVAL;
- new_bus = kmalloc(sizeof(struct mii_bus), GFP_KERNEL);
+ new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
if (NULL == new_bus)
return -ENOMEM;
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
index 56e5665..e85eb21 100644
--- a/drivers/net/gianfar_mii.h
+++ b/drivers/net/gianfar_mii.h
@@ -5,7 +5,7 @@
* Driver for the MDIO bus controller in the Gianfar register space
*
* Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ * Maintainer: Kumar Gala
*
* Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
*
diff --git a/drivers/net/gt96100eth.c b/drivers/net/gt96100eth.c
index 666cfbb..5958a63 100644
--- a/drivers/net/gt96100eth.c
+++ b/drivers/net/gt96100eth.c
@@ -72,8 +72,6 @@ static void dump_tx_desc(int dbg_lvl, struct net_device *dev, int i);
static void dump_rx_desc(int dbg_lvl, struct net_device *dev, int i);
static void dump_skb(int dbg_lvl, struct net_device *dev,
struct sk_buff *skb);
-static void dump_hw_addr(int dbg_lvl, struct net_device *dev,
- const char* pfx, unsigned char* addr_str);
static void update_stats(struct gt96100_private *gp);
static void abort(struct net_device *dev, u32 abort_bits);
static void hard_stop(struct net_device *dev);
@@ -334,13 +332,13 @@ dump_MII(int dbg_lvl, struct net_device *dev)
static void
dump_hw_addr(int dbg_lvl, struct net_device *dev, const char* pfx,
- unsigned char* addr_str)
+ const char* func, unsigned char* addr_str)
{
int i;
char buf[100], octet[5];
if (dbg_lvl <= GT96100_DEBUG) {
- strcpy(buf, pfx);
+ sprintf(buf, pfx, func);
for (i = 0; i < 6; i++) {
sprintf(octet, "%2.2x%s",
addr_str[i], i<5 ? ":" : "\n");
@@ -708,7 +706,7 @@ static int __init gt96100_probe1(struct pci_dev *pci, int port_num)
info("%s found at 0x%x, irq %d\n",
chip_name(gp->chip_rev), gtif->iobase, gtif->irq);
- dump_hw_addr(0, dev, "HW Address ", dev->dev_addr);
+ dump_hw_addr(0, dev, "%s: HW Address ", __FUNCTION__, dev->dev_addr);
info("%s chip revision=%d\n", chip_name(gp->chip_rev), gp->chip_rev);
info("%s ethernet port %d\n", chip_name(gp->chip_rev), gp->port_num);
info("external PHY ID1=0x%04x, ID2=0x%04x\n", phy_id1, phy_id2);
@@ -1488,7 +1486,7 @@ gt96100_set_rx_mode(struct net_device *dev)
gt96100_add_hash_entry(dev, dev->dev_addr);
for (mcptr = dev->mc_list; mcptr; mcptr = mcptr->next) {
- dump_hw_addr(2, dev, __FUNCTION__ ": addr=",
+ dump_hw_addr(2, dev, "%s: addr=", __FUNCTION__,
mcptr->dmi_addr);
gt96100_add_hash_entry(dev, mcptr->dmi_addr);
}
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index be191d8..ceb98fd 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -58,7 +58,7 @@
#include "ibmveth.h"
-#define DEBUG 1
+#undef DEBUG
#define ibmveth_printk(fmt, args...) \
printk(KERN_INFO "%s: " fmt, __FILE__, ## args)
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 6a3129b..9b8295e 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -1360,7 +1360,7 @@ static struct pci_driver ioc3_driver = {
static int __init ioc3_init_module(void)
{
- return pci_module_init(&ioc3_driver);
+ return pci_register_driver(&ioc3_driver);
}
static void __exit ioc3_cleanup_module(void)
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
index 9bf3468..2e7882e 100644
--- a/drivers/net/irda/ali-ircc.c
+++ b/drivers/net/irda/ali-ircc.c
@@ -40,6 +40,7 @@
#include <asm/byteorder.h>
#include <linux/pm.h>
+#include <linux/pm_legacy.h>
#include <net/irda/wrapper.h>
#include <net/irda/irda.h>
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 805714e..ee717d0 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -59,6 +59,7 @@
#include <asm/byteorder.h>
#include <linux/pm.h>
+#include <linux/pm_legacy.h>
#include <net/irda/wrapper.h>
#include <net/irda/irda.h>
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 76e0b9f..63d38fb 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -291,9 +291,9 @@ static void sa1100_irda_shutdown(struct sa1100_irda *si)
/*
* Suspend the IrDA interface.
*/
-static int sa1100_irda_suspend(struct device *_dev, pm_message_t state)
+static int sa1100_irda_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct net_device *dev = dev_get_drvdata(_dev);
+ struct net_device *dev = platform_get_drvdata(pdev);
struct sa1100_irda *si;
if (!dev)
@@ -316,9 +316,9 @@ static int sa1100_irda_suspend(struct device *_dev, pm_message_t state)
/*
* Resume the IrDA interface.
*/
-static int sa1100_irda_resume(struct device *_dev)
+static int sa1100_irda_resume(struct platform_device *pdev)
{
- struct net_device *dev = dev_get_drvdata(_dev);
+ struct net_device *dev = platform_get_drvdata(pdev);
struct sa1100_irda *si;
if (!dev)
@@ -886,9 +886,8 @@ static int sa1100_irda_init_iobuf(iobuff_t *io, int size)
return io->head ? 0 : -ENOMEM;
}
-static int sa1100_irda_probe(struct device *_dev)
+static int sa1100_irda_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(_dev);
struct net_device *dev;
struct sa1100_irda *si;
unsigned int baudrate_mask;
@@ -967,7 +966,7 @@ static int sa1100_irda_probe(struct device *_dev)
err = register_netdev(dev);
if (err == 0)
- dev_set_drvdata(&pdev->dev, dev);
+ platform_set_drvdata(pdev, dev);
if (err) {
err_mem_5:
@@ -985,9 +984,9 @@ static int sa1100_irda_probe(struct device *_dev)
return err;
}
-static int sa1100_irda_remove(struct device *_dev)
+static int sa1100_irda_remove(struct platform_device *pdev)
{
- struct net_device *dev = dev_get_drvdata(_dev);
+ struct net_device *dev = platform_get_drvdata(pdev);
if (dev) {
struct sa1100_irda *si = dev->priv;
@@ -1004,13 +1003,14 @@ static int sa1100_irda_remove(struct device *_dev)
return 0;
}
-static struct device_driver sa1100ir_driver = {
- .name = "sa11x0-ir",
- .bus = &platform_bus_type,
+static struct platform_driver sa1100ir_driver = {
.probe = sa1100_irda_probe,
.remove = sa1100_irda_remove,
.suspend = sa1100_irda_suspend,
.resume = sa1100_irda_resume,
+ .driver = {
+ .name = "sa11x0-ir",
+ },
};
static int __init sa1100_irda_init(void)
@@ -1023,12 +1023,12 @@ static int __init sa1100_irda_init(void)
if (power_level > 3)
power_level = 3;
- return driver_register(&sa1100ir_driver);
+ return platform_driver_register(&sa1100ir_driver);
}
static void __exit sa1100_irda_exit(void)
{
- driver_unregister(&sa1100ir_driver);
+ platform_driver_unregister(&sa1100ir_driver);
}
module_init(sa1100_irda_init);
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index a1d207f..ec94ecd 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -214,14 +214,15 @@ static int smsc_ircc_probe_transceiver_smsc_ircc_atc(int fir_base);
/* Power Management */
-static int smsc_ircc_suspend(struct device *dev, pm_message_t state);
-static int smsc_ircc_resume(struct device *dev);
+static int smsc_ircc_suspend(struct platform_device *dev, pm_message_t state);
+static int smsc_ircc_resume(struct platform_device *dev);
-static struct device_driver smsc_ircc_driver = {
- .name = SMSC_IRCC2_DRIVER_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver smsc_ircc_driver = {
.suspend = smsc_ircc_suspend,
.resume = smsc_ircc_resume,
+ .driver = {
+ .name = SMSC_IRCC2_DRIVER_NAME,
+ },
};
/* Transceivers for SMSC-ircc */
@@ -346,7 +347,7 @@ static int __init smsc_ircc_init(void)
IRDA_DEBUG(1, "%s\n", __FUNCTION__);
- ret = driver_register(&smsc_ircc_driver);
+ ret = platform_driver_register(&smsc_ircc_driver);
if (ret) {
IRDA_ERROR("%s, Can't register driver!\n", driver_name);
return ret;
@@ -378,7 +379,7 @@ static int __init smsc_ircc_init(void)
}
if (ret)
- driver_unregister(&smsc_ircc_driver);
+ platform_driver_unregister(&smsc_ircc_driver);
return ret;
}
@@ -491,7 +492,7 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u
err = PTR_ERR(self->pldev);
goto err_out5;
}
- dev_set_drvdata(&self->pldev->dev, self);
+ platform_set_drvdata(self->pldev, self);
IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name);
dev_count++;
@@ -1685,9 +1686,9 @@ static int smsc_ircc_net_close(struct net_device *dev)
return 0;
}
-static int smsc_ircc_suspend(struct device *dev, pm_message_t state)
+static int smsc_ircc_suspend(struct platform_device *dev, pm_message_t state)
{
- struct smsc_ircc_cb *self = dev_get_drvdata(dev);
+ struct smsc_ircc_cb *self = platform_get_drvdata(dev);
if (!self->io.suspended) {
IRDA_DEBUG(1, "%s, Suspending\n", driver_name);
@@ -1706,9 +1707,9 @@ static int smsc_ircc_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int smsc_ircc_resume(struct device *dev)
+static int smsc_ircc_resume(struct platform_device *dev)
{
- struct smsc_ircc_cb *self = dev_get_drvdata(dev);
+ struct smsc_ircc_cb *self = platform_get_drvdata(dev);
if (self->io.suspended) {
IRDA_DEBUG(1, "%s, Waking up\n", driver_name);
@@ -1788,7 +1789,7 @@ static void __exit smsc_ircc_cleanup(void)
smsc_ircc_close(dev_self[i]);
}
- driver_unregister(&smsc_ircc_driver);
+ platform_driver_unregister(&smsc_ircc_driver);
}
/*
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 2fb3101..b039bd8 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -194,7 +194,7 @@ out:
* Probe for a SONIC ethernet controller on a Mips Jazz board.
* Actually probing is superfluous but we're paranoid.
*/
-static int __init jazz_sonic_probe(struct device *device)
+static int __init jazz_sonic_probe(struct platform_device *pdev)
{
struct net_device *dev;
struct sonic_local *lp;
@@ -212,8 +212,8 @@ static int __init jazz_sonic_probe(struct device *device)
return -ENOMEM;
lp = netdev_priv(dev);
- lp->device = device;
- SET_NETDEV_DEV(dev, device);
+ lp->device = &pdev->dev;
+ SET_NETDEV_DEV(dev, &pdev->dev);
SET_MODULE_OWNER(dev);
netdev_boot_setup_check(dev);
@@ -264,9 +264,9 @@ MODULE_PARM_DESC(sonic_debug, "jazzsonic debug level (1-4)");
#include "sonic.c"
-static int __devexit jazz_sonic_device_remove (struct device *device)
+static int __devexit jazz_sonic_device_remove (struct platform_device *pdev)
{
- struct net_device *dev = device->driver_data;
+ struct net_device *dev = platform_get_drvdata(pdev);
struct sonic_local* lp = netdev_priv(dev);
unregister_netdev (dev);
@@ -278,18 +278,19 @@ static int __devexit jazz_sonic_device_remove (struct device *device)
return 0;
}
-static struct device_driver jazz_sonic_driver = {
- .name = jazz_sonic_string,
- .bus = &platform_bus_type,
+static struct platform_driver jazz_sonic_driver = {
.probe = jazz_sonic_probe,
.remove = __devexit_p(jazz_sonic_device_remove),
+ .driver = {
+ .name = jazz_sonic_string,
+ },
};
static int __init jazz_sonic_init_module(void)
{
int err;
- if ((err = driver_register(&jazz_sonic_driver))) {
+ if ((err = platform_driver_register(&jazz_sonic_driver))) {
printk(KERN_ERR "Driver registration failed\n");
return err;
}
@@ -313,7 +314,7 @@ out_unregister:
static void __exit jazz_sonic_cleanup_module(void)
{
- driver_unregister(&jazz_sonic_driver);
+ platform_driver_unregister(&jazz_sonic_driver);
if (jazz_sonic_device) {
platform_device_unregister(jazz_sonic_device);
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index 9ef4592..02d5c68 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -525,7 +525,7 @@ int __init mac_nubus_sonic_probe(struct net_device* dev)
return macsonic_init(dev);
}
-static int __init mac_sonic_probe(struct device *device)
+static int __init mac_sonic_probe(struct platform_device *device)
{
struct net_device *dev;
struct sonic_local *lp;
@@ -537,8 +537,8 @@ static int __init mac_sonic_probe(struct device *device)
return -ENOMEM;
lp = netdev_priv(dev);
- lp->device = device;
- SET_NETDEV_DEV(dev, device);
+ lp->device = &device->dev;
+ SET_NETDEV_DEV(dev, &device->dev);
SET_MODULE_OWNER(dev);
/* This will catch fatal stuff like -ENOMEM as well as success */
@@ -579,9 +579,9 @@ MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
#include "sonic.c"
-static int __devexit mac_sonic_device_remove (struct device *device)
+static int __devexit mac_sonic_device_remove (struct platform_device *device)
{
- struct net_device *dev = device->driver_data;
+ struct net_device *dev = platform_get_drvdata(device);
struct sonic_local* lp = netdev_priv(dev);
unregister_netdev (dev);
@@ -592,18 +592,19 @@ static int __devexit mac_sonic_device_remove (struct device *device)
return 0;
}
-static struct device_driver mac_sonic_driver = {
- .name = mac_sonic_string,
- .bus = &platform_bus_type,
+static struct platform_driver mac_sonic_driver = {
.probe = mac_sonic_probe,
.remove = __devexit_p(mac_sonic_device_remove),
+ .driver = {
+ .name = mac_sonic_string,
+ },
};
static int __init mac_sonic_init_module(void)
{
int err;
- if ((err = driver_register(&mac_sonic_driver))) {
+ if ((err = platform_driver_register(&mac_sonic_driver))) {
printk(KERN_ERR "Driver registration failed\n");
return err;
}
@@ -628,7 +629,7 @@ out_unregister:
static void __exit mac_sonic_cleanup_module(void)
{
- driver_unregister(&mac_sonic_driver);
+ platform_driver_unregister(&mac_sonic_driver);
if (mac_sonic_device) {
platform_device_unregister(mac_sonic_device);
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 71f2c67..3cb9b3f 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1387,9 +1387,8 @@ static void mv643xx_netpoll(struct net_device *netdev)
* Input : struct device *
* Output : -ENOMEM if failed , 0 if success
*/
-static int mv643xx_eth_probe(struct device *ddev)
+static int mv643xx_eth_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(ddev);
struct mv643xx_eth_platform_data *pd;
int port_num = pdev->id;
struct mv643xx_private *mp;
@@ -1402,7 +1401,7 @@ static int mv643xx_eth_probe(struct device *ddev)
if (!dev)
return -ENOMEM;
- dev_set_drvdata(ddev, dev);
+ platform_set_drvdata(pdev, dev);
mp = netdev_priv(dev);
@@ -1546,21 +1545,20 @@ out:
return err;
}
-static int mv643xx_eth_remove(struct device *ddev)
+static int mv643xx_eth_remove(struct platform_device *pdev)
{
- struct net_device *dev = dev_get_drvdata(ddev);
+ struct net_device *dev = platform_get_drvdata(pdev);
unregister_netdev(dev);
flush_scheduled_work();
free_netdev(dev);
- dev_set_drvdata(ddev, NULL);
+ platform_set_drvdata(pdev, NULL);
return 0;
}
-static int mv643xx_eth_shared_probe(struct device *ddev)
+static int mv643xx_eth_shared_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(ddev);
struct resource *res;
printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n");
@@ -1578,7 +1576,7 @@ static int mv643xx_eth_shared_probe(struct device *ddev)
}
-static int mv643xx_eth_shared_remove(struct device *ddev)
+static int mv643xx_eth_shared_remove(struct platform_device *pdev)
{
iounmap(mv643xx_eth_shared_base);
mv643xx_eth_shared_base = NULL;
@@ -1586,18 +1584,20 @@ static int mv643xx_eth_shared_remove(struct device *ddev)
return 0;
}
-static struct device_driver mv643xx_eth_driver = {
- .name = MV643XX_ETH_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver mv643xx_eth_driver = {
.probe = mv643xx_eth_probe,
.remove = mv643xx_eth_remove,
+ .driver = {
+ .name = MV643XX_ETH_NAME,
+ },
};
-static struct device_driver mv643xx_eth_shared_driver = {
- .name = MV643XX_ETH_SHARED_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver mv643xx_eth_shared_driver = {
.probe = mv643xx_eth_shared_probe,
.remove = mv643xx_eth_shared_remove,
+ .driver = {
+ .name = MV643XX_ETH_SHARED_NAME,
+ },
};
/*
@@ -1613,11 +1613,11 @@ static int __init mv643xx_init_module(void)
{
int rc;
- rc = driver_register(&mv643xx_eth_shared_driver);
+ rc = platform_driver_register(&mv643xx_eth_shared_driver);
if (!rc) {
- rc = driver_register(&mv643xx_eth_driver);
+ rc = platform_driver_register(&mv643xx_eth_driver);
if (rc)
- driver_unregister(&mv643xx_eth_shared_driver);
+ platform_driver_unregister(&mv643xx_eth_shared_driver);
}
return rc;
}
@@ -1633,8 +1633,8 @@ static int __init mv643xx_init_module(void)
*/
static void __exit mv643xx_cleanup_module(void)
{
- driver_unregister(&mv643xx_eth_driver);
- driver_unregister(&mv643xx_eth_shared_driver);
+ platform_driver_unregister(&mv643xx_eth_driver);
+ platform_driver_unregister(&mv643xx_eth_shared_driver);
}
module_init(mv643xx_init_module);
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 159b56a..14a76f7 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1346,10 +1346,8 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
} else {
if (netif_msg_probe(tp)) {
printk(KERN_ERR PFX
- "Cannot find PowerManagement capability. "
- "Aborting.\n");
+ "PowerManagement capability not found.\n");
}
- goto err_out_mwi;
}
/* make sure PCI base addr 1 is MMIO */
@@ -2516,7 +2514,7 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
} while (boguscnt > 0);
if (boguscnt <= 0) {
- if (net_ratelimit() && netif_msg_intr(tp)) {
+ if (netif_msg_intr(tp) && net_ratelimit() ) {
printk(KERN_WARNING
"%s: Too much work at interrupt!\n", dev->name);
}
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
index 110e777..b2acedb 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -1,8 +1,8 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
- *
- * ########################################################################
+ * Copyright (C) 2000, 2005 MIPS Technologies, Inc. All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ * Copyright (C) 2004 Ralf Baechle <ralf@linux-mips.org>
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
@@ -17,15 +17,13 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
- * ########################################################################
- *
* SAA9730 ethernet driver.
*
* Changes:
- * Angelo Dell'Aera <buffer@antifork.org> : Conversion to the new PCI API (pci_driver).
- * Conversion to spinlocks.
- * Error handling fixes.
- *
+ * Angelo Dell'Aera <buffer@antifork.org> : Conversion to the new PCI API
+ * (pci_driver).
+ * Conversion to spinlocks.
+ * Error handling fixes.
*/
#include <linux/init.h>
@@ -36,8 +34,11 @@
#include <linux/skbuff.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
+#include <linux/types.h>
#include <asm/addrspace.h>
+#include <asm/io.h>
+
#include <asm/mips-boards/prom.h>
#include "saa9730.h"
@@ -51,8 +52,8 @@ int lan_saa9730_debug;
#define DRV_MODULE_NAME "saa9730"
static struct pci_device_id saa9730_pci_tbl[] = {
- { PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA9370,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA9730,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ 0, }
};
@@ -61,50 +62,48 @@ MODULE_DEVICE_TABLE(pci, saa9730_pci_tbl);
/* Non-zero only if the current card is a PCI with BIOS-set IRQ. */
static unsigned int pci_irq_line;
-#define INL(a) inl((unsigned long)a)
-#define OUTL(x,a) outl(x,(unsigned long)a)
-
static void evm_saa9730_enable_lan_int(struct lan_saa9730_private *lp)
{
- OUTL(INL(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
+ outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
&lp->evm_saa9730_regs->InterruptBlock1);
- OUTL(INL(&lp->evm_saa9730_regs->InterruptStatus1) | EVM_LAN_INT,
+ outl(readl(&lp->evm_saa9730_regs->InterruptStatus1) | EVM_LAN_INT,
&lp->evm_saa9730_regs->InterruptStatus1);
- OUTL(INL(&lp->evm_saa9730_regs->InterruptEnable1) | EVM_LAN_INT |
+ outl(readl(&lp->evm_saa9730_regs->InterruptEnable1) | EVM_LAN_INT |
EVM_MASTER_EN, &lp->evm_saa9730_regs->InterruptEnable1);
}
+
static void evm_saa9730_disable_lan_int(struct lan_saa9730_private *lp)
{
- OUTL(INL(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
+ outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
&lp->evm_saa9730_regs->InterruptBlock1);
- OUTL(INL(&lp->evm_saa9730_regs->InterruptEnable1) & ~EVM_LAN_INT,
+ outl(readl(&lp->evm_saa9730_regs->InterruptEnable1) & ~EVM_LAN_INT,
&lp->evm_saa9730_regs->InterruptEnable1);
}
static void evm_saa9730_clear_lan_int(struct lan_saa9730_private *lp)
{
- OUTL(EVM_LAN_INT, &lp->evm_saa9730_regs->InterruptStatus1);
+ outl(EVM_LAN_INT, &lp->evm_saa9730_regs->InterruptStatus1);
}
static void evm_saa9730_block_lan_int(struct lan_saa9730_private *lp)
{
- OUTL(INL(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
+ outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
&lp->evm_saa9730_regs->InterruptBlock1);
}
static void evm_saa9730_unblock_lan_int(struct lan_saa9730_private *lp)
{
- OUTL(INL(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
+ outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
&lp->evm_saa9730_regs->InterruptBlock1);
}
-static void show_saa9730_regs(struct lan_saa9730_private *lp)
+static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp)
{
int i, j;
- printk("TxmBufferA = %x\n", lp->TxmBuffer[0][0]);
- printk("TxmBufferB = %x\n", lp->TxmBuffer[1][0]);
- printk("RcvBufferA = %x\n", lp->RcvBuffer[0][0]);
- printk("RcvBufferB = %x\n", lp->RcvBuffer[1][0]);
+ printk("TxmBufferA = %p\n", lp->TxmBuffer[0][0]);
+ printk("TxmBufferB = %p\n", lp->TxmBuffer[1][0]);
+ printk("RcvBufferA = %p\n", lp->RcvBuffer[0][0]);
+ printk("RcvBufferB = %p\n", lp->RcvBuffer[1][0]);
for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
for (j = 0; j < LAN_SAA9730_TXM_Q_SIZE; j++) {
printk("TxmBuffer[%d][%d] = %x\n", i, j,
@@ -120,13 +119,13 @@ static void show_saa9730_regs(struct lan_saa9730_private *lp)
}
}
printk("lp->evm_saa9730_regs->InterruptBlock1 = %x\n",
- INL(&lp->evm_saa9730_regs->InterruptBlock1));
+ readl(&lp->evm_saa9730_regs->InterruptBlock1));
printk("lp->evm_saa9730_regs->InterruptStatus1 = %x\n",
- INL(&lp->evm_saa9730_regs->InterruptStatus1));
+ readl(&lp->evm_saa9730_regs->InterruptStatus1));
printk("lp->evm_saa9730_regs->InterruptEnable1 = %x\n",
- INL(&lp->evm_saa9730_regs->InterruptEnable1));
+ readl(&lp->evm_saa9730_regs->InterruptEnable1));
printk("lp->lan_saa9730_regs->Ok2Use = %x\n",
- INL(&lp->lan_saa9730_regs->Ok2Use));
+ readl(&lp->lan_saa9730_regs->Ok2Use));
printk("lp->NextTxmBufferIndex = %x\n", lp->NextTxmBufferIndex);
printk("lp->NextTxmPacketIndex = %x\n", lp->NextTxmPacketIndex);
printk("lp->PendingTxmBufferIndex = %x\n",
@@ -134,23 +133,23 @@ static void show_saa9730_regs(struct lan_saa9730_private *lp)
printk("lp->PendingTxmPacketIndex = %x\n",
lp->PendingTxmPacketIndex);
printk("lp->lan_saa9730_regs->LanDmaCtl = %x\n",
- INL(&lp->lan_saa9730_regs->LanDmaCtl));
+ readl(&lp->lan_saa9730_regs->LanDmaCtl));
printk("lp->lan_saa9730_regs->DmaStatus = %x\n",
- INL(&lp->lan_saa9730_regs->DmaStatus));
+ readl(&lp->lan_saa9730_regs->DmaStatus));
printk("lp->lan_saa9730_regs->CamCtl = %x\n",
- INL(&lp->lan_saa9730_regs->CamCtl));
+ readl(&lp->lan_saa9730_regs->CamCtl));
printk("lp->lan_saa9730_regs->TxCtl = %x\n",
- INL(&lp->lan_saa9730_regs->TxCtl));
+ readl(&lp->lan_saa9730_regs->TxCtl));
printk("lp->lan_saa9730_regs->TxStatus = %x\n",
- INL(&lp->lan_saa9730_regs->TxStatus));
+ readl(&lp->lan_saa9730_regs->TxStatus));
printk("lp->lan_saa9730_regs->RxCtl = %x\n",
- INL(&lp->lan_saa9730_regs->RxCtl));
+ readl(&lp->lan_saa9730_regs->RxCtl));
printk("lp->lan_saa9730_regs->RxStatus = %x\n",
- INL(&lp->lan_saa9730_regs->RxStatus));
+ readl(&lp->lan_saa9730_regs->RxStatus));
for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) {
- OUTL(i, &lp->lan_saa9730_regs->CamAddress);
+ outl(i, &lp->lan_saa9730_regs->CamAddress);
printk("lp->lan_saa9730_regs->CamData = %x\n",
- INL(&lp->lan_saa9730_regs->CamData));
+ readl(&lp->lan_saa9730_regs->CamData));
}
printk("lp->stats.tx_packets = %lx\n", lp->stats.tx_packets);
printk("lp->stats.tx_errors = %lx\n", lp->stats.tx_errors);
@@ -178,17 +177,17 @@ static void show_saa9730_regs(struct lan_saa9730_private *lp)
lp->stats.rx_length_errors);
printk("lp->lan_saa9730_regs->DebugPCIMasterAddr = %x\n",
- INL(&lp->lan_saa9730_regs->DebugPCIMasterAddr));
+ readl(&lp->lan_saa9730_regs->DebugPCIMasterAddr));
printk("lp->lan_saa9730_regs->DebugLanTxStateMachine = %x\n",
- INL(&lp->lan_saa9730_regs->DebugLanTxStateMachine));
+ readl(&lp->lan_saa9730_regs->DebugLanTxStateMachine));
printk("lp->lan_saa9730_regs->DebugLanRxStateMachine = %x\n",
- INL(&lp->lan_saa9730_regs->DebugLanRxStateMachine));
+ readl(&lp->lan_saa9730_regs->DebugLanRxStateMachine));
printk("lp->lan_saa9730_regs->DebugLanTxFifoPointers = %x\n",
- INL(&lp->lan_saa9730_regs->DebugLanTxFifoPointers));
+ readl(&lp->lan_saa9730_regs->DebugLanTxFifoPointers));
printk("lp->lan_saa9730_regs->DebugLanRxFifoPointers = %x\n",
- INL(&lp->lan_saa9730_regs->DebugLanRxFifoPointers));
+ readl(&lp->lan_saa9730_regs->DebugLanRxFifoPointers));
printk("lp->lan_saa9730_regs->DebugLanCtlStateMachine = %x\n",
- INL(&lp->lan_saa9730_regs->DebugLanCtlStateMachine));
+ readl(&lp->lan_saa9730_regs->DebugLanCtlStateMachine));
}
static void lan_saa9730_buffer_init(struct lan_saa9730_private *lp)
@@ -214,98 +213,108 @@ static void lan_saa9730_buffer_init(struct lan_saa9730_private *lp)
}
}
-static int lan_saa9730_allocate_buffers(struct lan_saa9730_private *lp)
+static void lan_saa9730_free_buffers(struct pci_dev *pdev,
+ struct lan_saa9730_private *lp)
{
- unsigned int mem_size;
- void *Pa;
- unsigned int i, j, RcvBufferSize, TxmBufferSize;
- unsigned int buffer_start;
+ pci_free_consistent(pdev, lp->buffer_size, lp->buffer_start,
+ lp->dma_addr);
+}
- /*
- * Allocate all RX and TX packets in one chunk.
- * The Rx and Tx packets must be PACKET_SIZE aligned.
- */
- mem_size = ((LAN_SAA9730_RCV_Q_SIZE + LAN_SAA9730_TXM_Q_SIZE) *
- LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_BUFFERS) +
- LAN_SAA9730_PACKET_SIZE;
- buffer_start =
- (unsigned int) kmalloc(mem_size, GFP_DMA | GFP_KERNEL);
-
- if (!buffer_start)
- return -ENOMEM;
-
- /*
- * Set DMA buffer to kseg1 (uncached).
- * Make sure to flush before using it uncached.
- */
- Pa = (void *) KSEG1ADDR((buffer_start + LAN_SAA9730_PACKET_SIZE) &
- ~(LAN_SAA9730_PACKET_SIZE - 1));
- dma_cache_wback_inv((unsigned long) Pa, mem_size);
+static int lan_saa9730_allocate_buffers(struct pci_dev *pdev,
+ struct lan_saa9730_private *lp)
+{
+ void *Pa;
+ unsigned int i, j, rxoffset, txoffset;
+ int ret;
/* Initialize buffer space */
- RcvBufferSize = LAN_SAA9730_PACKET_SIZE;
- TxmBufferSize = LAN_SAA9730_PACKET_SIZE;
lp->DmaRcvPackets = LAN_SAA9730_RCV_Q_SIZE;
lp->DmaTxmPackets = LAN_SAA9730_TXM_Q_SIZE;
+ /* Initialize Rx Buffer Index */
+ lp->NextRcvPacketIndex = 0;
+ lp->NextRcvBufferIndex = 0;
+
+ /* Set current buffer index & next available packet index */
+ lp->NextTxmPacketIndex = 0;
+ lp->NextTxmBufferIndex = 0;
+ lp->PendingTxmPacketIndex = 0;
+ lp->PendingTxmBufferIndex = 0;
+
+ /*
+ * Allocate all RX and TX packets in one chunk.
+ * The Rx and Tx packets must be PACKET_SIZE aligned.
+ */
+ lp->buffer_size = ((LAN_SAA9730_RCV_Q_SIZE + LAN_SAA9730_TXM_Q_SIZE) *
+ LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_BUFFERS) +
+ LAN_SAA9730_PACKET_SIZE;
+ lp->buffer_start = pci_alloc_consistent(pdev, lp->buffer_size,
+ &lp->dma_addr);
+ if (!lp->buffer_start) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ Pa = (void *)ALIGN((unsigned long)lp->buffer_start,
+ LAN_SAA9730_PACKET_SIZE);
+
+ rxoffset = Pa - lp->buffer_start;
+
/* Init RX buffers */
for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
for (j = 0; j < LAN_SAA9730_RCV_Q_SIZE; j++) {
*(unsigned int *) Pa =
cpu_to_le32(RXSF_READY <<
RX_STAT_CTL_OWNER_SHF);
- lp->RcvBuffer[i][j] = (unsigned int) Pa;
- Pa += RcvBufferSize;
+ lp->RcvBuffer[i][j] = Pa;
+ Pa += LAN_SAA9730_PACKET_SIZE;
}
}
+ txoffset = Pa - lp->buffer_start;
+
/* Init TX buffers */
for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
for (j = 0; j < LAN_SAA9730_TXM_Q_SIZE; j++) {
*(unsigned int *) Pa =
cpu_to_le32(TXSF_EMPTY <<
TX_STAT_CTL_OWNER_SHF);
- lp->TxmBuffer[i][j] = (unsigned int) Pa;
- Pa += TxmBufferSize;
+ lp->TxmBuffer[i][j] = Pa;
+ Pa += LAN_SAA9730_PACKET_SIZE;
}
}
- /*
- * Set rx buffer A and rx buffer B to point to the first two buffer
+ /*
+ * Set rx buffer A and rx buffer B to point to the first two buffer
* spaces.
*/
- OUTL(PHYSADDR(lp->RcvBuffer[0][0]),
+ outl(lp->dma_addr + rxoffset,
&lp->lan_saa9730_regs->RxBuffA);
- OUTL(PHYSADDR(lp->RcvBuffer[1][0]),
+ outl(lp->dma_addr + rxoffset +
+ LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_RCV_Q_SIZE,
&lp->lan_saa9730_regs->RxBuffB);
- /* Initialize Buffer Index */
- lp->NextRcvPacketIndex = 0;
- lp->NextRcvToUseIsA = 1;
-
- /* Set current buffer index & next availble packet index */
- lp->NextTxmPacketIndex = 0;
- lp->NextTxmBufferIndex = 0;
- lp->PendingTxmPacketIndex = 0;
- lp->PendingTxmBufferIndex = 0;
-
- /*
+ /*
* Set txm_buf_a and txm_buf_b to point to the first two buffer
- * space
+ * space
*/
- OUTL(PHYSADDR(lp->TxmBuffer[0][0]),
+ outl(lp->dma_addr + txoffset,
&lp->lan_saa9730_regs->TxBuffA);
- OUTL(PHYSADDR(lp->TxmBuffer[1][0]),
+ outl(lp->dma_addr + txoffset +
+ LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_TXM_Q_SIZE,
&lp->lan_saa9730_regs->TxBuffB);
/* Set packet number */
- OUTL((lp->DmaRcvPackets << PK_COUNT_RX_A_SHF) |
+ outl((lp->DmaRcvPackets << PK_COUNT_RX_A_SHF) |
(lp->DmaRcvPackets << PK_COUNT_RX_B_SHF) |
(lp->DmaTxmPackets << PK_COUNT_TX_A_SHF) |
(lp->DmaTxmPackets << PK_COUNT_TX_B_SHF),
&lp->lan_saa9730_regs->PacketCount);
return 0;
+
+out:
+ return ret;
}
static int lan_saa9730_cam_load(struct lan_saa9730_private *lp)
@@ -317,8 +326,8 @@ static int lan_saa9730_cam_load(struct lan_saa9730_private *lp)
for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) {
/* First set address to where data is written */
- OUTL(i, &lp->lan_saa9730_regs->CamAddress);
- OUTL((NetworkAddress[0] << 24) | (NetworkAddress[1] << 16)
+ outl(i, &lp->lan_saa9730_regs->CamAddress);
+ outl((NetworkAddress[0] << 24) | (NetworkAddress[1] << 16)
| (NetworkAddress[2] << 8) | NetworkAddress[3],
&lp->lan_saa9730_regs->CamData);
NetworkAddress += 4;
@@ -328,8 +337,7 @@ static int lan_saa9730_cam_load(struct lan_saa9730_private *lp)
static int lan_saa9730_cam_init(struct net_device *dev)
{
- struct lan_saa9730_private *lp =
- (struct lan_saa9730_private *) dev->priv;
+ struct lan_saa9730_private *lp = netdev_priv(dev);
unsigned int i;
/* Copy MAC-address into all entries. */
@@ -347,7 +355,7 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
/* Check link status, spin here till station is not busy. */
i = 0;
- while (INL(&lp->lan_saa9730_regs->StationMgmtCtl) & MD_CA_BUSY) {
+ while (readl(&lp->lan_saa9730_regs->StationMgmtCtl) & MD_CA_BUSY) {
i++;
if (i > 100) {
printk("Error: lan_saa9730_mii_init: timeout\n");
@@ -357,12 +365,12 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
}
/* Now set the control and address register. */
- OUTL(MD_CA_BUSY | PHY_STATUS | PHY_ADDRESS << MD_CA_PHY_SHF,
+ outl(MD_CA_BUSY | PHY_STATUS | PHY_ADDRESS << MD_CA_PHY_SHF,
&lp->lan_saa9730_regs->StationMgmtCtl);
/* check link status, spin here till station is not busy */
i = 0;
- while (INL(&lp->lan_saa9730_regs->StationMgmtCtl) & MD_CA_BUSY) {
+ while (readl(&lp->lan_saa9730_regs->StationMgmtCtl) & MD_CA_BUSY) {
i++;
if (i > 100) {
printk("Error: lan_saa9730_mii_init: timeout\n");
@@ -375,7 +383,7 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
mdelay(1);
/* Check the link status. */
- if (INL(&lp->lan_saa9730_regs->StationMgmtData) &
+ if (readl(&lp->lan_saa9730_regs->StationMgmtData) &
PHY_STATUS_LINK_UP) {
/* Link is up. */
return 0;
@@ -383,14 +391,14 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
/* Link is down, reset the PHY first. */
/* set PHY address = 'CONTROL' */
- OUTL(PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR | PHY_CONTROL,
+ outl(PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR | PHY_CONTROL,
&lp->lan_saa9730_regs->StationMgmtCtl);
/* Wait for 1 ms. */
mdelay(1);
/* set 'CONTROL' = force reset and renegotiate */
- OUTL(PHY_CONTROL_RESET | PHY_CONTROL_AUTO_NEG |
+ outl(PHY_CONTROL_RESET | PHY_CONTROL_AUTO_NEG |
PHY_CONTROL_RESTART_AUTO_NEG,
&lp->lan_saa9730_regs->StationMgmtData);
@@ -398,12 +406,12 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
mdelay(50);
/* set 'BUSY' to start operation */
- OUTL(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR |
+ outl(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR |
PHY_CONTROL, &lp->lan_saa9730_regs->StationMgmtCtl);
/* await completion */
i = 0;
- while (INL(&lp->lan_saa9730_regs->StationMgmtCtl) &
+ while (readl(&lp->lan_saa9730_regs->StationMgmtCtl) &
MD_CA_BUSY) {
i++;
if (i > 100) {
@@ -419,13 +427,13 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
for (l = 0; l < 2; l++) {
/* set PHY address = 'STATUS' */
- OUTL(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF |
+ outl(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF |
PHY_STATUS,
&lp->lan_saa9730_regs->StationMgmtCtl);
/* await completion */
i = 0;
- while (INL(&lp->lan_saa9730_regs->StationMgmtCtl) &
+ while (readl(&lp->lan_saa9730_regs->StationMgmtCtl) &
MD_CA_BUSY) {
i++;
if (i > 100) {
@@ -440,7 +448,7 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
mdelay(3000);
/* check the link status */
- if (INL(&lp->lan_saa9730_regs->StationMgmtData) &
+ if (readl(&lp->lan_saa9730_regs->StationMgmtData) &
PHY_STATUS_LINK_UP) {
/* link is up */
break;
@@ -454,7 +462,7 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
static int lan_saa9730_control_init(struct lan_saa9730_private *lp)
{
/* Initialize DMA control register. */
- OUTL((LANMB_ANY << DMA_CTL_MAX_XFER_SHF) |
+ outl((LANMB_ANY << DMA_CTL_MAX_XFER_SHF) |
(LANEND_LITTLE << DMA_CTL_ENDIAN_SHF) |
(LAN_SAA9730_RCV_Q_INT_THRESHOLD << DMA_CTL_RX_INT_COUNT_SHF)
| DMA_CTL_RX_INT_TO_EN | DMA_CTL_RX_INT_EN |
@@ -462,27 +470,27 @@ static int lan_saa9730_control_init(struct lan_saa9730_private *lp)
&lp->lan_saa9730_regs->LanDmaCtl);
/* Initial MAC control register. */
- OUTL((MACCM_MII << MAC_CONTROL_CONN_SHF) | MAC_CONTROL_FULL_DUP,
+ outl((MACCM_MII << MAC_CONTROL_CONN_SHF) | MAC_CONTROL_FULL_DUP,
&lp->lan_saa9730_regs->MacCtl);
/* Initialize CAM control register. */
- OUTL(CAM_CONTROL_COMP_EN | CAM_CONTROL_BROAD_ACC,
+ outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_BROAD_ACC,
&lp->lan_saa9730_regs->CamCtl);
- /*
+ /*
* Initialize CAM enable register, only turn on first entry, should
- * contain own addr.
+ * contain own addr.
*/
- OUTL(0x0001, &lp->lan_saa9730_regs->CamEnable);
+ outl(0x0001, &lp->lan_saa9730_regs->CamEnable);
/* Initialize Tx control register */
- OUTL(TX_CTL_EN_COMP, &lp->lan_saa9730_regs->TxCtl);
+ outl(TX_CTL_EN_COMP, &lp->lan_saa9730_regs->TxCtl);
/* Initialize Rcv control register */
- OUTL(RX_CTL_STRIP_CRC, &lp->lan_saa9730_regs->RxCtl);
+ outl(RX_CTL_STRIP_CRC, &lp->lan_saa9730_regs->RxCtl);
/* Reset DMA engine */
- OUTL(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
+ outl(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
return 0;
}
@@ -492,21 +500,21 @@ static int lan_saa9730_stop(struct lan_saa9730_private *lp)
int i;
/* Stop DMA first */
- OUTL(INL(&lp->lan_saa9730_regs->LanDmaCtl) &
+ outl(readl(&lp->lan_saa9730_regs->LanDmaCtl) &
~(DMA_CTL_EN_TX_DMA | DMA_CTL_EN_RX_DMA),
&lp->lan_saa9730_regs->LanDmaCtl);
/* Set the SW Reset bits in DMA and MAC control registers */
- OUTL(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
- OUTL(INL(&lp->lan_saa9730_regs->MacCtl) | MAC_CONTROL_RESET,
+ outl(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
+ outl(readl(&lp->lan_saa9730_regs->MacCtl) | MAC_CONTROL_RESET,
&lp->lan_saa9730_regs->MacCtl);
- /*
+ /*
* Wait for MAC reset to have finished. The reset bit is auto cleared
* when the reset is done.
*/
i = 0;
- while (INL(&lp->lan_saa9730_regs->MacCtl) & MAC_CONTROL_RESET) {
+ while (readl(&lp->lan_saa9730_regs->MacCtl) & MAC_CONTROL_RESET) {
i++;
if (i > 100) {
printk
@@ -524,7 +532,7 @@ static int lan_saa9730_dma_init(struct lan_saa9730_private *lp)
/* Stop lan controller. */
lan_saa9730_stop(lp);
- OUTL(LAN_SAA9730_DEFAULT_TIME_OUT_CNT,
+ outl(LAN_SAA9730_DEFAULT_TIME_OUT_CNT,
&lp->lan_saa9730_regs->Timeout);
return 0;
@@ -536,28 +544,27 @@ static int lan_saa9730_start(struct lan_saa9730_private *lp)
/* Initialize Rx Buffer Index */
lp->NextRcvPacketIndex = 0;
- lp->NextRcvToUseIsA = 1;
+ lp->NextRcvBufferIndex = 0;
- /* Set current buffer index & next availble packet index */
+ /* Set current buffer index & next available packet index */
lp->NextTxmPacketIndex = 0;
lp->NextTxmBufferIndex = 0;
lp->PendingTxmPacketIndex = 0;
lp->PendingTxmBufferIndex = 0;
- OUTL(INL(&lp->lan_saa9730_regs->LanDmaCtl) | DMA_CTL_EN_TX_DMA |
+ outl(readl(&lp->lan_saa9730_regs->LanDmaCtl) | DMA_CTL_EN_TX_DMA |
DMA_CTL_EN_RX_DMA, &lp->lan_saa9730_regs->LanDmaCtl);
/* For Tx, turn on MAC then DMA */
- OUTL(INL(&lp->lan_saa9730_regs->TxCtl) | TX_CTL_TX_EN,
+ outl(readl(&lp->lan_saa9730_regs->TxCtl) | TX_CTL_TX_EN,
&lp->lan_saa9730_regs->TxCtl);
/* For Rx, turn on DMA then MAC */
- OUTL(INL(&lp->lan_saa9730_regs->RxCtl) | RX_CTL_RX_EN,
+ outl(readl(&lp->lan_saa9730_regs->RxCtl) | RX_CTL_RX_EN,
&lp->lan_saa9730_regs->RxCtl);
- /* Set Ok2Use to let hardware owns the buffers */
- OUTL(OK2USE_RX_A | OK2USE_RX_B | OK2USE_TX_A | OK2USE_TX_B,
- &lp->lan_saa9730_regs->Ok2Use);
+ /* Set Ok2Use to let hardware own the buffers. */
+ outl(OK2USE_RX_A | OK2USE_RX_B, &lp->lan_saa9730_regs->Ok2Use);
return 0;
}
@@ -572,8 +579,7 @@ static int lan_saa9730_restart(struct lan_saa9730_private *lp)
static int lan_saa9730_tx(struct net_device *dev)
{
- struct lan_saa9730_private *lp =
- (struct lan_saa9730_private *) dev->priv;
+ struct lan_saa9730_private *lp = netdev_priv(dev);
unsigned int *pPacket;
unsigned int tx_status;
@@ -581,13 +587,11 @@ static int lan_saa9730_tx(struct net_device *dev)
printk("lan_saa9730_tx interrupt\n");
/* Clear interrupt. */
- OUTL(DMA_STATUS_MAC_TX_INT, &lp->lan_saa9730_regs->DmaStatus);
+ outl(DMA_STATUS_MAC_TX_INT, &lp->lan_saa9730_regs->DmaStatus);
while (1) {
- pPacket =
- (unsigned int *) lp->TxmBuffer[lp->
- PendingTxmBufferIndex]
- [lp->PendingTxmPacketIndex];
+ pPacket = lp->TxmBuffer[lp->PendingTxmBufferIndex]
+ [lp->PendingTxmPacketIndex];
/* Get status of first packet transmitted. */
tx_status = le32_to_cpu(*pPacket);
@@ -605,23 +609,22 @@ static int lan_saa9730_tx(struct net_device *dev)
lp->stats.tx_errors++;
if (tx_status &
(TX_STATUS_EX_COLL << TX_STAT_CTL_STATUS_SHF))
- lp->stats.tx_aborted_errors++;
+ lp->stats.tx_aborted_errors++;
if (tx_status &
- (TX_STATUS_LATE_COLL <<
- TX_STAT_CTL_STATUS_SHF)) lp->stats.
- tx_window_errors++;
+ (TX_STATUS_LATE_COLL << TX_STAT_CTL_STATUS_SHF))
+ lp->stats.tx_window_errors++;
if (tx_status &
(TX_STATUS_L_CARR << TX_STAT_CTL_STATUS_SHF))
- lp->stats.tx_carrier_errors++;
+ lp->stats.tx_carrier_errors++;
if (tx_status &
(TX_STATUS_UNDER << TX_STAT_CTL_STATUS_SHF))
- lp->stats.tx_fifo_errors++;
+ lp->stats.tx_fifo_errors++;
if (tx_status &
(TX_STATUS_SQ_ERR << TX_STAT_CTL_STATUS_SHF))
- lp->stats.tx_heartbeat_errors++;
+ lp->stats.tx_heartbeat_errors++;
lp->stats.collisions +=
- tx_status & TX_STATUS_TX_COLL_MSK;
+ tx_status & TX_STATUS_TX_COLL_MSK;
}
/* Free buffer. */
@@ -636,21 +639,15 @@ static int lan_saa9730_tx(struct net_device *dev)
}
}
- /* Make sure A and B are available to hardware. */
- OUTL(OK2USE_TX_A | OK2USE_TX_B, &lp->lan_saa9730_regs->Ok2Use);
-
- if (netif_queue_stopped(dev)) {
- /* The tx buffer is no longer full. */
- netif_wake_queue(dev);
- }
+ /* The tx buffer is no longer full. */
+ netif_wake_queue(dev);
return 0;
}
static int lan_saa9730_rx(struct net_device *dev)
{
- struct lan_saa9730_private *lp =
- (struct lan_saa9730_private *) dev->priv;
+ struct lan_saa9730_private *lp = netdev_priv(dev);
int len = 0;
struct sk_buff *skb = 0;
unsigned int rx_status;
@@ -663,16 +660,13 @@ static int lan_saa9730_rx(struct net_device *dev)
printk("lan_saa9730_rx interrupt\n");
/* Clear receive interrupts. */
- OUTL(DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT |
+ outl(DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT |
DMA_STATUS_RX_TO_INT, &lp->lan_saa9730_regs->DmaStatus);
/* Address next packet */
- if (lp->NextRcvToUseIsA)
- BufferIndex = 0;
- else
- BufferIndex = 1;
+ BufferIndex = lp->NextRcvBufferIndex;
PacketIndex = lp->NextRcvPacketIndex;
- pPacket = (unsigned int *) lp->RcvBuffer[BufferIndex][PacketIndex];
+ pPacket = lp->RcvBuffer[BufferIndex][PacketIndex];
rx_status = le32_to_cpu(*pPacket);
/* Process each packet. */
@@ -715,51 +709,39 @@ static int lan_saa9730_rx(struct net_device *dev)
lp->stats.rx_errors++;
if (rx_status &
(RX_STATUS_CRC_ERR << RX_STAT_CTL_STATUS_SHF))
- lp->stats.rx_crc_errors++;
+ lp->stats.rx_crc_errors++;
if (rx_status &
- (RX_STATUS_ALIGN_ERR <<
- RX_STAT_CTL_STATUS_SHF)) lp->stats.
- rx_frame_errors++;
+ (RX_STATUS_ALIGN_ERR << RX_STAT_CTL_STATUS_SHF))
+ lp->stats.rx_frame_errors++;
if (rx_status &
(RX_STATUS_OVERFLOW << RX_STAT_CTL_STATUS_SHF))
- lp->stats.rx_fifo_errors++;
+ lp->stats.rx_fifo_errors++;
if (rx_status &
(RX_STATUS_LONG_ERR << RX_STAT_CTL_STATUS_SHF))
- lp->stats.rx_length_errors++;
+ lp->stats.rx_length_errors++;
}
/* Indicate we have processed the buffer. */
- *pPacket =
- cpu_to_le32(RXSF_READY << RX_STAT_CTL_OWNER_SHF);
+ *pPacket = cpu_to_le32(RXSF_READY << RX_STAT_CTL_OWNER_SHF);
+
+ /* Make sure A or B is available to hardware as appropriate. */
+ outl(BufferIndex ? OK2USE_RX_B : OK2USE_RX_A,
+ &lp->lan_saa9730_regs->Ok2Use);
/* Go to next packet in sequence. */
lp->NextRcvPacketIndex++;
if (lp->NextRcvPacketIndex >= LAN_SAA9730_RCV_Q_SIZE) {
lp->NextRcvPacketIndex = 0;
- if (BufferIndex) {
- lp->NextRcvToUseIsA = 1;
- } else {
- lp->NextRcvToUseIsA = 0;
- }
+ lp->NextRcvBufferIndex ^= 1;
}
- OUTL(OK2USE_RX_A | OK2USE_RX_B,
- &lp->lan_saa9730_regs->Ok2Use);
/* Address next packet */
- if (lp->NextRcvToUseIsA)
- BufferIndex = 0;
- else
- BufferIndex = 1;
+ BufferIndex = lp->NextRcvBufferIndex;
PacketIndex = lp->NextRcvPacketIndex;
- pPacket =
- (unsigned int *) lp->
- RcvBuffer[BufferIndex][PacketIndex];
+ pPacket = lp->RcvBuffer[BufferIndex][PacketIndex];
rx_status = le32_to_cpu(*pPacket);
}
- /* Make sure A and B are available to hardware. */
- OUTL(OK2USE_RX_A | OK2USE_RX_B, &lp->lan_saa9730_regs->Ok2Use);
-
return 0;
}
@@ -767,8 +749,7 @@ static irqreturn_t lan_saa9730_interrupt(const int irq, void *dev_id,
struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_id;
- struct lan_saa9730_private *lp =
- (struct lan_saa9730_private *) dev->priv;
+ struct lan_saa9730_private *lp = netdev_priv(dev);
if (lan_saa9730_debug > 5)
printk("lan_saa9730_interrupt\n");
@@ -780,11 +761,11 @@ static irqreturn_t lan_saa9730_interrupt(const int irq, void *dev_id,
evm_saa9730_clear_lan_int(lp);
/* Service pending transmit interrupts. */
- if (INL(&lp->lan_saa9730_regs->DmaStatus) & DMA_STATUS_MAC_TX_INT)
+ if (readl(&lp->lan_saa9730_regs->DmaStatus) & DMA_STATUS_MAC_TX_INT)
lan_saa9730_tx(dev);
/* Service pending receive interrupts. */
- if (INL(&lp->lan_saa9730_regs->DmaStatus) &
+ if (readl(&lp->lan_saa9730_regs->DmaStatus) &
(DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT |
DMA_STATUS_RX_TO_INT)) lan_saa9730_rx(dev);
@@ -794,15 +775,9 @@ static irqreturn_t lan_saa9730_interrupt(const int irq, void *dev_id,
return IRQ_HANDLED;
}
-static int lan_saa9730_open_fail(struct net_device *dev)
-{
- return -ENODEV;
-}
-
static int lan_saa9730_open(struct net_device *dev)
{
- struct lan_saa9730_private *lp =
- (struct lan_saa9730_private *) dev->priv;
+ struct lan_saa9730_private *lp = netdev_priv(dev);
/* Associate IRQ with lan_saa9730_interrupt */
if (request_irq(dev->irq, &lan_saa9730_interrupt, 0, "SAA9730 Eth",
@@ -834,15 +809,13 @@ static int lan_saa9730_write(struct lan_saa9730_private *lp,
int PacketIndex;
if (lan_saa9730_debug > 5)
- printk("lan_saa9730_write: skb=%08x\n",
- (unsigned int) skb);
+ printk("lan_saa9730_write: skb=%p\n", skb);
BufferIndex = lp->NextTxmBufferIndex;
PacketIndex = lp->NextTxmPacketIndex;
- tx_status =
- le32_to_cpu(*(unsigned int *) lp->
- TxmBuffer[BufferIndex][PacketIndex]);
+ tx_status = le32_to_cpu(*(unsigned int *)lp->TxmBuffer[BufferIndex]
+ [PacketIndex]);
if ((tx_status & TX_STAT_CTL_OWNER_MSK) !=
(TXSF_EMPTY << TX_STAT_CTL_OWNER_SHF)) {
if (lan_saa9730_debug > 4)
@@ -858,29 +831,29 @@ static int lan_saa9730_write(struct lan_saa9730_private *lp,
lp->NextTxmBufferIndex ^= 1;
}
- pbPacketData =
- (unsigned char *) lp->TxmBuffer[BufferIndex][PacketIndex];
+ pbPacketData = lp->TxmBuffer[BufferIndex][PacketIndex];
pbPacketData += 4;
/* copy the bits */
memcpy(pbPacketData, pbData, len);
/* Set transmit status for hardware */
- *(unsigned int *) lp->TxmBuffer[BufferIndex][PacketIndex] =
- cpu_to_le32((TXSF_READY << TX_STAT_CTL_OWNER_SHF) |
- (TX_STAT_CTL_INT_AFTER_TX << TX_STAT_CTL_FRAME_SHF)
- | (len << TX_STAT_CTL_LENGTH_SHF));
-
- /* Set hardware tx buffer. */
- OUTL(OK2USE_TX_A | OK2USE_TX_B, &lp->lan_saa9730_regs->Ok2Use);
+ *(unsigned int *)lp->TxmBuffer[BufferIndex][PacketIndex] =
+ cpu_to_le32((TXSF_READY << TX_STAT_CTL_OWNER_SHF) |
+ (TX_STAT_CTL_INT_AFTER_TX <<
+ TX_STAT_CTL_FRAME_SHF) |
+ (len << TX_STAT_CTL_LENGTH_SHF));
+
+ /* Make sure A or B is available to hardware as appropriate. */
+ outl(BufferIndex ? OK2USE_TX_B : OK2USE_TX_A,
+ &lp->lan_saa9730_regs->Ok2Use);
return 0;
}
static void lan_saa9730_tx_timeout(struct net_device *dev)
{
- struct lan_saa9730_private *lp =
- (struct lan_saa9730_private *) dev->priv;
+ struct lan_saa9730_private *lp = netdev_priv(dev);
/* Transmitter timeout, serious problems */
lp->stats.tx_errors++;
@@ -889,20 +862,19 @@ static void lan_saa9730_tx_timeout(struct net_device *dev)
lan_saa9730_restart(lp);
dev->trans_start = jiffies;
- netif_start_queue(dev);
+ netif_wake_queue(dev);
}
static int lan_saa9730_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
- struct lan_saa9730_private *lp =
- (struct lan_saa9730_private *) dev->priv;
+ struct lan_saa9730_private *lp = netdev_priv(dev);
unsigned long flags;
int skblen;
int len;
if (lan_saa9730_debug > 4)
- printk("Send packet: skb=%08x\n", (unsigned int) skb);
+ printk("Send packet: skb=%p\n", skb);
skblen = skb->len;
@@ -912,8 +884,7 @@ static int lan_saa9730_start_xmit(struct sk_buff *skb,
if (lan_saa9730_write(lp, skb, skblen)) {
spin_unlock_irqrestore(&lp->lock, flags);
- printk("Error when writing packet to controller: skb=%08x\n",
- (unsigned int) skb);
+ printk("Error when writing packet to controller: skb=%p\n", skb);
netif_stop_queue(dev);
return -1;
}
@@ -922,7 +893,7 @@ static int lan_saa9730_start_xmit(struct sk_buff *skb,
lp->stats.tx_packets++;
dev->trans_start = jiffies;
- netif_start_queue(dev);
+ netif_wake_queue(dev);
dev_kfree_skb(skb);
spin_unlock_irqrestore(&lp->lock, flags);
@@ -932,8 +903,7 @@ static int lan_saa9730_start_xmit(struct sk_buff *skb,
static int lan_saa9730_close(struct net_device *dev)
{
- struct lan_saa9730_private *lp =
- (struct lan_saa9730_private *) dev->priv;
+ struct lan_saa9730_private *lp = netdev_priv(dev);
if (lan_saa9730_debug > 1)
printk("lan_saa9730_close:\n");
@@ -955,33 +925,31 @@ static int lan_saa9730_close(struct net_device *dev)
static struct net_device_stats *lan_saa9730_get_stats(struct net_device
*dev)
{
- struct lan_saa9730_private *lp =
- (struct lan_saa9730_private *) dev->priv;
+ struct lan_saa9730_private *lp = netdev_priv(dev);
return &lp->stats;
}
static void lan_saa9730_set_multicast(struct net_device *dev)
{
- struct lan_saa9730_private *lp =
- (struct lan_saa9730_private *) dev->priv;
+ struct lan_saa9730_private *lp = netdev_priv(dev);
/* Stop the controller */
lan_saa9730_stop(lp);
if (dev->flags & IFF_PROMISC) {
/* accept all packets */
- OUTL(CAM_CONTROL_COMP_EN | CAM_CONTROL_STATION_ACC |
+ outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_STATION_ACC |
CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC,
&lp->lan_saa9730_regs->CamCtl);
} else {
if (dev->flags & IFF_ALLMULTI) {
/* accept all multicast packets */
- OUTL(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |
+ outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |
CAM_CONTROL_BROAD_ACC,
&lp->lan_saa9730_regs->CamCtl);
} else {
- /*
+ /*
* Will handle the multicast stuff later. -carstenl
*/
}
@@ -993,91 +961,86 @@ static void lan_saa9730_set_multicast(struct net_device *dev)
static void __devexit saa9730_remove_one(struct pci_dev *pdev)
{
- struct net_device *dev = pci_get_drvdata(pdev);
-
- if (dev) {
- unregister_netdev(dev);
- kfree(dev->priv);
- free_netdev(dev);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
- }
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct lan_saa9730_private *lp = netdev_priv(dev);
+
+ if (dev) {
+ unregister_netdev(dev);
+ lan_saa9730_free_buffers(pdev, lp);
+ iounmap(lp->lan_saa9730_regs);
+ iounmap(lp->evm_saa9730_regs);
+ free_netdev(dev);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+ }
}
-static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
+static int lan_saa9730_init(struct net_device *dev, struct pci_dev *pdev,
+ unsigned long ioaddr, int irq)
{
- struct lan_saa9730_private *lp;
+ struct lan_saa9730_private *lp = netdev_priv(dev);
unsigned char ethernet_addr[6];
- int ret = 0;
+ int ret;
- dev->open = lan_saa9730_open_fail;
+ if (get_ethernet_addr(ethernet_addr)) {
+ ret = -ENODEV;
+ goto out;
+ }
- if (get_ethernet_addr(ethernet_addr))
- return -ENODEV;
-
memcpy(dev->dev_addr, ethernet_addr, 6);
dev->base_addr = ioaddr;
dev->irq = irq;
-
- /*
- * Make certain the data structures used by the controller are aligned
- * and DMAble.
- */
- /*
- * XXX: that is obviously broken - kfree() won't be happy with us.
- */
- lp = (struct lan_saa9730_private *) (((unsigned long)
- kmalloc(sizeof(*lp) + 7,
- GFP_DMA | GFP_KERNEL)
- + 7) & ~7);
- if (!lp)
- return -ENOMEM;
-
- dev->priv = lp;
- memset(lp, 0, sizeof(*lp));
+ lp->pci_dev = pdev;
/* Set SAA9730 LAN base address. */
- lp->lan_saa9730_regs = (t_lan_saa9730_regmap *) (ioaddr +
- SAA9730_LAN_REGS_ADDR);
+ lp->lan_saa9730_regs = ioremap(ioaddr + SAA9730_LAN_REGS_ADDR,
+ SAA9730_LAN_REGS_SIZE);
+ if (!lp->lan_saa9730_regs) {
+ ret = -ENOMEM;
+ goto out;
+ }
/* Set SAA9730 EVM base address. */
- lp->evm_saa9730_regs = (t_evm_saa9730_regmap *) (ioaddr +
- SAA9730_EVM_REGS_ADDR);
+ lp->evm_saa9730_regs = ioremap(ioaddr + SAA9730_EVM_REGS_ADDR,
+ SAA9730_EVM_REGS_SIZE);
+ if (!lp->evm_saa9730_regs) {
+ ret = -ENOMEM;
+ goto out_iounmap_lan;
+ }
/* Allocate LAN RX/TX frame buffer space. */
- /* FIXME: a leak */
- if ((ret = lan_saa9730_allocate_buffers(lp)))
- goto out;
+ if ((ret = lan_saa9730_allocate_buffers(pdev, lp)))
+ goto out_iounmap;
/* Stop LAN controller. */
- if ((ret = lan_saa9730_stop(lp)))
- goto out;
-
+ if ((ret = lan_saa9730_stop(lp)))
+ goto out_free_consistent;
+
/* Initialize CAM registers. */
if ((ret = lan_saa9730_cam_init(dev)))
- goto out;
+ goto out_free_consistent;
/* Initialize MII registers. */
if ((ret = lan_saa9730_mii_init(lp)))
- goto out;
+ goto out_free_consistent;
/* Initialize control registers. */
- if ((ret = lan_saa9730_control_init(lp)))
- goto out;
-
+ if ((ret = lan_saa9730_control_init(lp)))
+ goto out_free_consistent;
+
/* Load CAM registers. */
- if ((ret = lan_saa9730_cam_load(lp)))
- goto out;
-
+ if ((ret = lan_saa9730_cam_load(lp)))
+ goto out_free_consistent;
+
/* Initialize DMA context registers. */
if ((ret = lan_saa9730_dma_init(lp)))
- goto out;
-
+ goto out_free_consistent;
+
spin_lock_init(&lp->lock);
-
+
dev->open = lan_saa9730_open;
dev->hard_start_xmit = lan_saa9730_start_xmit;
dev->stop = lan_saa9730_close;
@@ -1086,44 +1049,43 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
dev->tx_timeout = lan_saa9730_tx_timeout;
dev->watchdog_timeo = (HZ >> 1);
dev->dma = 0;
-
- ret = register_netdev(dev);
+
+ ret = register_netdev (dev);
if (ret)
- goto out;
+ goto out_free_consistent;
+
return 0;
- out:
- kfree(dev->priv);
+out_free_consistent:
+ lan_saa9730_free_buffers(pdev, lp);
+out_iounmap:
+ iounmap(lp->evm_saa9730_regs);
+out_iounmap_lan:
+ iounmap(lp->lan_saa9730_regs);
+out:
return ret;
}
static int __devinit saa9730_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- struct net_device *dev;
- unsigned int pci_ioaddr;
+ struct net_device *dev = NULL;
+ unsigned long pci_ioaddr;
int err;
if (lan_saa9730_debug > 1)
printk("saa9730.c: PCI bios is present, checking for devices...\n");
- err = -ENOMEM;
- dev = alloc_etherdev(0);
- if (!dev)
- goto out;
-
- SET_MODULE_OWNER(dev);
-
err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_ERR "Cannot enable PCI device, aborting.\n");
- goto out1;
- }
+ if (err) {
+ printk(KERN_ERR "Cannot enable PCI device, aborting.\n");
+ goto out;
+ }
err = pci_request_regions(pdev, DRV_MODULE_NAME);
if (err) {
printk(KERN_ERR "Cannot obtain PCI resources, aborting.\n");
- goto out2;
+ goto out_disable_pdev;
}
pci_irq_line = pdev->irq;
@@ -1132,49 +1094,54 @@ static int __devinit saa9730_init_one(struct pci_dev *pdev, const struct pci_dev
pci_ioaddr = pci_resource_start(pdev, 1);
pci_set_master(pdev);
- printk("Found SAA9730 (PCI) at %#x, irq %d.\n",
+ printk("Found SAA9730 (PCI) at %lx, irq %d.\n",
pci_ioaddr, pci_irq_line);
- err = lan_saa9730_init(dev, pci_ioaddr, pci_irq_line);
+ dev = alloc_etherdev(sizeof(struct lan_saa9730_private));
+ if (!dev)
+ goto out_disable_pdev;
+
+ err = lan_saa9730_init(dev, pdev, pci_ioaddr, pci_irq_line);
if (err) {
- printk("Lan init failed");
- goto out2;
+ printk("LAN init failed");
+ goto out_free_netdev;
}
pci_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
return 0;
-
-out2:
- pci_disable_device(pdev);
-out1:
+
+out_free_netdev:
free_netdev(dev);
+out_disable_pdev:
+ pci_disable_device(pdev);
out:
+ pci_set_drvdata(pdev, NULL);
return err;
}
static struct pci_driver saa9730_driver = {
- .name = DRV_MODULE_NAME,
- .id_table = saa9730_pci_tbl,
- .probe = saa9730_init_one,
- .remove = __devexit_p(saa9730_remove_one),
+ .name = DRV_MODULE_NAME,
+ .id_table = saa9730_pci_tbl,
+ .probe = saa9730_init_one,
+ .remove = __devexit_p(saa9730_remove_one),
};
static int __init saa9730_init(void)
{
- return pci_module_init(&saa9730_driver);
+ return pci_module_init(&saa9730_driver);
}
static void __exit saa9730_cleanup(void)
{
- pci_unregister_driver(&saa9730_driver);
+ pci_unregister_driver(&saa9730_driver);
}
module_init(saa9730_init);
module_exit(saa9730_cleanup);
-
-
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_DESCRIPTION("Philips SAA9730 ethernet driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/saa9730.h b/drivers/net/saa9730.h
index 9e9da6b..a7e9d29 100644
--- a/drivers/net/saa9730.h
+++ b/drivers/net/saa9730.h
@@ -1,6 +1,7 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 2000, 2005 MIPS Technologies, Inc. All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
*
* ########################################################################
*
@@ -265,6 +266,7 @@
/* The SAA9730 (LAN) controller register map, as seen via the PCI-bus. */
#define SAA9730_LAN_REGS_ADDR 0x20400
+#define SAA9730_LAN_REGS_SIZE 0x00400
struct lan_saa9730_regmap {
volatile unsigned int TxBuffA; /* 0x20400 */
@@ -309,6 +311,7 @@ typedef volatile struct lan_saa9730_regmap t_lan_saa9730_regmap;
/* The SAA9730 (EVM) controller register map, as seen via the PCI-bus. */
#define SAA9730_EVM_REGS_ADDR 0x02000
+#define SAA9730_EVM_REGS_SIZE 0x00400
struct evm_saa9730_regmap {
volatile unsigned int InterruptStatus1; /* 0x2000 */
@@ -329,16 +332,32 @@ typedef volatile struct evm_saa9730_regmap t_evm_saa9730_regmap;
struct lan_saa9730_private {
+ /*
+ * Rx/Tx packet buffers.
+ * The Rx and Tx packets must be PACKET_SIZE aligned.
+ */
+ void *buffer_start;
+ unsigned int buffer_size;
+
+ /*
+ * DMA address of beginning of this object, returned
+ * by pci_alloc_consistent().
+ */
+ dma_addr_t dma_addr;
+
+ /* Pointer to the associated pci device structure */
+ struct pci_dev *pci_dev;
+
/* Pointer for the SAA9730 LAN controller register set. */
t_lan_saa9730_regmap *lan_saa9730_regs;
/* Pointer to the SAA9730 EVM register. */
t_evm_saa9730_regmap *evm_saa9730_regs;
- /* TRUE if the next buffer to write is RxBuffA, FALSE if RxBuffB. */
- unsigned char NextRcvToUseIsA;
/* Rcv buffer Index. */
unsigned char NextRcvPacketIndex;
+ /* Next buffer index. */
+ unsigned char NextRcvBufferIndex;
/* Index of next packet to use in that buffer. */
unsigned char NextTxmPacketIndex;
@@ -353,13 +372,8 @@ struct lan_saa9730_private {
unsigned char DmaRcvPackets;
unsigned char DmaTxmPackets;
- unsigned char RcvAIndex; /* index into RcvBufferSpace[] for Blk A */
- unsigned char RcvBIndex; /* index into RcvBufferSpace[] for Blk B */
-
- unsigned int
- TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
- unsigned int
- RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
+ void *TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
+ void *RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
unsigned int TxBufferFree[LAN_SAA9730_BUFFERS];
unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6];
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 74d5f1a..28bf2e6 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -155,6 +155,12 @@ MODULE_LICENSE("GPL");
#define MEMORY_WAIT_TIME 16
/*
+ * The maximum number of processing loops allowed for each call to the
+ * IRQ handler.
+ */
+#define MAX_IRQ_LOOPS 8
+
+/*
* This selects whether TX packets are sent one by one to the SMC91x internal
* memory and throttled until transmission completes. This may prevent
* RX overruns a litle by keeping much of the memory free for RX packets
@@ -684,7 +690,6 @@ static void smc_hardware_send_pkt(unsigned long data)
/* queue the packet for TX */
SMC_SET_MMU_CMD(MC_ENQUEUE);
- SMC_ACK_INT(IM_TX_EMPTY_INT);
smc_special_unlock(&lp->lock);
dev->trans_start = jiffies;
@@ -1207,6 +1212,7 @@ static void smc_phy_configure(void *data)
smc_phy_check_media(dev, 1);
smc_phy_configure_exit:
+ SMC_SELECT_BANK(2);
spin_unlock_irq(&lp->lock);
lp->work_pending = 0;
}
@@ -1305,7 +1311,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
SMC_SET_INT_MASK(0);
/* set a timeout value, so I don't stay here forever */
- timeout = 8;
+ timeout = MAX_IRQ_LOOPS;
do {
status = SMC_GET_INT();
@@ -1372,10 +1378,13 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* restore register states */
SMC_SET_PTR(saved_pointer);
SMC_SET_INT_MASK(mask);
-
spin_unlock(&lp->lock);
- DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout);
+ if (timeout == MAX_IRQ_LOOPS)
+ PRINTK("%s: spurious interrupt (mask = 0x%02x)\n",
+ dev->name, mask);
+ DBG(3, "%s: Interrupt done (%d loops)\n",
+ dev->name, MAX_IRQ_LOOPS - timeout);
/*
* We return IRQ_HANDLED unconditionally here even if there was
@@ -2183,9 +2192,8 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device *
* 0 --> there is a device
* anything else, error
*/
-static int smc_drv_probe(struct device *dev)
+static int smc_drv_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev;
struct resource *res;
unsigned int __iomem *addr;
@@ -2212,7 +2220,7 @@ static int smc_drv_probe(struct device *dev)
goto out_release_io;
}
SET_MODULE_OWNER(ndev);
- SET_NETDEV_DEV(ndev, dev);
+ SET_NETDEV_DEV(ndev, &pdev->dev);
ndev->dma = (unsigned char)-1;
ndev->irq = platform_get_irq(pdev, 0);
@@ -2233,7 +2241,7 @@ static int smc_drv_probe(struct device *dev)
goto out_release_attrib;
}
- dev_set_drvdata(dev, ndev);
+ platform_set_drvdata(pdev, ndev);
ret = smc_probe(ndev, addr);
if (ret != 0)
goto out_iounmap;
@@ -2249,7 +2257,7 @@ static int smc_drv_probe(struct device *dev)
return 0;
out_iounmap:
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
iounmap(addr);
out_release_attrib:
smc_release_attrib(pdev);
@@ -2263,14 +2271,13 @@ static int smc_drv_probe(struct device *dev)
return ret;
}
-static int smc_drv_remove(struct device *dev)
+static int smc_drv_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct net_device *ndev = dev_get_drvdata(dev);
+ struct net_device *ndev = platform_get_drvdata(pdev);
struct smc_local *lp = netdev_priv(ndev);
struct resource *res;
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
unregister_netdev(ndev);
@@ -2295,9 +2302,9 @@ static int smc_drv_remove(struct device *dev)
return 0;
}
-static int smc_drv_suspend(struct device *dev, pm_message_t state)
+static int smc_drv_suspend(struct platform_device *dev, pm_message_t state)
{
- struct net_device *ndev = dev_get_drvdata(dev);
+ struct net_device *ndev = platform_get_drvdata(dev);
if (ndev) {
if (netif_running(ndev)) {
@@ -2309,14 +2316,13 @@ static int smc_drv_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int smc_drv_resume(struct device *dev)
+static int smc_drv_resume(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct net_device *ndev = dev_get_drvdata(dev);
+ struct net_device *ndev = platform_get_drvdata(dev);
if (ndev) {
struct smc_local *lp = netdev_priv(ndev);
- smc_enable_device(pdev);
+ smc_enable_device(dev);
if (netif_running(ndev)) {
smc_reset(ndev);
smc_enable(ndev);
@@ -2328,13 +2334,14 @@ static int smc_drv_resume(struct device *dev)
return 0;
}
-static struct device_driver smc_driver = {
- .name = CARDNAME,
- .bus = &platform_bus_type,
+static struct platform_driver smc_driver = {
.probe = smc_drv_probe,
.remove = smc_drv_remove,
.suspend = smc_drv_suspend,
.resume = smc_drv_resume,
+ .driver = {
+ .name = CARDNAME,
+ },
};
static int __init smc_init(void)
@@ -2348,12 +2355,12 @@ static int __init smc_init(void)
#endif
#endif
- return driver_register(&smc_driver);
+ return platform_driver_register(&smc_driver);
}
static void __exit smc_cleanup(void)
{
- driver_unregister(&smc_driver);
+ platform_driver_unregister(&smc_driver);
}
module_init(smc_init);
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 817f200..5c2824b 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -100,14 +100,14 @@
#define SMC_IO_SHIFT 0
#define SMC_NOWAIT 1
-#define SMC_inb(a, r) inb((a) + (r))
-#define SMC_insb(a, r, p, l) insb((a) + (r), p, (l))
-#define SMC_inw(a, r) inw((a) + (r))
-#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
-#define SMC_outb(v, a, r) outb(v, (a) + (r))
-#define SMC_outsb(a, r, p, l) outsb((a) + (r), p, (l))
-#define SMC_outw(v, a, r) outw(v, (a) + (r))
-#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
+#define SMC_inb(a, r) readb((a) + (r))
+#define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l))
+#define SMC_inw(a, r) readw((a) + (r))
+#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
+#define SMC_outb(v, a, r) writeb(v, (a) + (r))
+#define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l))
+#define SMC_outw(v, a, r) writew(v, (a) + (r))
+#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
#define set_irq_type(irq, type) do {} while (0)
@@ -289,6 +289,38 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l)
#define RPC_LSA_DEFAULT RPC_LED_TX_RX
#define RPC_LSB_DEFAULT RPC_LED_100_10
+#elif defined(CONFIG_SOC_AU1X00)
+
+#include <au1xxx.h>
+
+/* We can only do 16-bit reads and writes in the static memory space. */
+#define SMC_CAN_USE_8BIT 0
+#define SMC_CAN_USE_16BIT 1
+#define SMC_CAN_USE_32BIT 0
+#define SMC_IO_SHIFT 0
+#define SMC_NOWAIT 1
+
+#define SMC_inw(a, r) au_readw((unsigned long)((a) + (r)))
+#define SMC_insw(a, r, p, l) \
+ do { \
+ unsigned long _a = (unsigned long)((a) + (r)); \
+ int _l = (l); \
+ u16 *_p = (u16 *)(p); \
+ while (_l-- > 0) \
+ *_p++ = au_readw(_a); \
+ } while(0)
+#define SMC_outw(v, a, r) au_writew(v, (unsigned long)((a) + (r)))
+#define SMC_outsw(a, r, p, l) \
+ do { \
+ unsigned long _a = (unsigned long)((a) + (r)); \
+ int _l = (l); \
+ const u16 *_p = (const u16 *)(p); \
+ while (_l-- > 0) \
+ au_writew(*_p++ , _a); \
+ } while(0)
+
+#define set_irq_type(irq, type) do {} while (0)
+
#else
#define SMC_CAN_USE_8BIT 1
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index c796f41..0d765f1 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -2290,7 +2290,6 @@ spider_net_remove(struct pci_dev *pdev)
}
static struct pci_driver spider_net_driver = {
- .owner = THIS_MODULE,
.name = spider_net_driver_name,
.id_table = spider_net_pci_tbl,
.probe = spider_net_probe,
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index de39956..081717d 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -128,6 +128,8 @@ static struct pci_device_id gem_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_SUNGEM,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_GMAC,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{0, }
};
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
index d04c918..4f75696 100644
--- a/drivers/net/tokenring/proteon.c
+++ b/drivers/net/tokenring/proteon.c
@@ -344,9 +344,10 @@ module_param_array(dma, int, NULL, 0);
static struct platform_device *proteon_dev[ISATR_MAX_ADAPTERS];
-static struct device_driver proteon_driver = {
- .name = "proteon",
- .bus = &platform_bus_type,
+static struct platform_driver proteon_driver = {
+ .driver = {
+ .name = "proteon",
+ },
};
static int __init proteon_init(void)
@@ -355,7 +356,7 @@ static int __init proteon_init(void)
struct platform_device *pdev;
int i, num = 0, err = 0;
- err = driver_register(&proteon_driver);
+ err = platform_driver_register(&proteon_driver);
if (err)
return err;
@@ -372,7 +373,7 @@ static int __init proteon_init(void)
err = setup_card(dev, &pdev->dev);
if (!err) {
proteon_dev[i] = pdev;
- dev_set_drvdata(&pdev->dev, dev);
+ platform_set_drvdata(pdev, dev);
++num;
} else {
platform_device_unregister(pdev);
@@ -399,17 +400,17 @@ static void __exit proteon_cleanup(void)
if (!pdev)
continue;
- dev = dev_get_drvdata(&pdev->dev);
+ dev = platform_get_drvdata(pdev);
unregister_netdev(dev);
release_region(dev->base_addr, PROTEON_IO_EXTENT);
free_irq(dev->irq, dev);
free_dma(dev->dma);
tmsdev_term(dev);
free_netdev(dev);
- dev_set_drvdata(&pdev->dev, NULL);
+ platform_set_drvdata(pdev, NULL);
platform_device_unregister(pdev);
}
- driver_unregister(&proteon_driver);
+ platform_driver_unregister(&proteon_driver);
}
module_init(proteon_init);
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
index 72cf708..d6ba41c 100644
--- a/drivers/net/tokenring/skisa.c
+++ b/drivers/net/tokenring/skisa.c
@@ -354,9 +354,10 @@ module_param_array(dma, int, NULL, 0);
static struct platform_device *sk_isa_dev[ISATR_MAX_ADAPTERS];
-static struct device_driver sk_isa_driver = {
- .name = "skisa",
- .bus = &platform_bus_type,
+static struct platform_driver sk_isa_driver = {
+ .driver = {
+ .name = "skisa",
+ },
};
static int __init sk_isa_init(void)
@@ -365,7 +366,7 @@ static int __init sk_isa_init(void)
struct platform_device *pdev;
int i, num = 0, err = 0;
- err = driver_register(&sk_isa_driver);
+ err = platform_driver_register(&sk_isa_driver);
if (err)
return err;
@@ -382,7 +383,7 @@ static int __init sk_isa_init(void)
err = setup_card(dev, &pdev->dev);
if (!err) {
sk_isa_dev[i] = pdev;
- dev_set_drvdata(&sk_isa_dev[i]->dev, dev);
+ platform_set_drvdata(sk_isa_dev[i], dev);
++num;
} else {
platform_device_unregister(pdev);
@@ -409,17 +410,17 @@ static void __exit sk_isa_cleanup(void)
if (!pdev)
continue;
- dev = dev_get_drvdata(&pdev->dev);
+ dev = platform_get_drvdata(pdev);
unregister_netdev(dev);
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
free_irq(dev->irq, dev);
free_dma(dev->dma);
tmsdev_term(dev);
free_netdev(dev);
- dev_set_drvdata(&pdev->dev, NULL);
+ platform_set_drvdata(pdev, NULL);
platform_device_unregister(pdev);
}
- driver_unregister(&sk_isa_driver);
+ platform_driver_unregister(&sk_isa_driver);
}
module_init(sk_isa_init);
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index a01efa6..1fd0466 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -192,7 +192,9 @@ static int cisco_rx(struct sk_buff *skb)
"uptime %ud%uh%um%us)\n",
dev->name, days, hrs,
min, sec);
+#if 0
netif_carrier_on(dev);
+#endif
hdlc->state.cisco.up = 1;
}
}
@@ -225,7 +227,9 @@ static void cisco_timer(unsigned long arg)
hdlc->state.cisco.settings.timeout * HZ)) {
hdlc->state.cisco.up = 0;
printk(KERN_INFO "%s: Link down\n", dev->name);
+#if 0
netif_carrier_off(dev);
+#endif
}
cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ,
@@ -261,8 +265,10 @@ static void cisco_stop(struct net_device *dev)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
del_timer_sync(&hdlc->state.cisco.timer);
+#if 0
if (netif_carrier_ok(dev))
netif_carrier_off(dev);
+#endif
hdlc->state.cisco.up = 0;
hdlc->state.cisco.request_sent = 0;
}
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index e1601d3..523afe1 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -545,8 +545,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
hdlc->state.fr.reliable = reliable;
if (reliable) {
+#if 0
if (!netif_carrier_ok(dev))
netif_carrier_on(dev);
+#endif
hdlc->state.fr.n391cnt = 0; /* Request full status */
hdlc->state.fr.dce_changed = 1;
@@ -560,8 +562,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
}
}
} else {
+#if 0
if (netif_carrier_ok(dev))
netif_carrier_off(dev);
+#endif
while (pvc) { /* Deactivate all PVCs */
pvc_carrier(0, pvc);
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc_generic.c
index cdd4c09c..46cef8f 100644
--- a/drivers/net/wan/hdlc_generic.c
+++ b/drivers/net/wan/hdlc_generic.c
@@ -79,11 +79,13 @@ static void __hdlc_set_carrier_on(struct net_device *dev)
hdlc_device *hdlc = dev_to_hdlc(dev);
if (hdlc->proto.start)
return hdlc->proto.start(dev);
+#if 0
#ifdef DEBUG_LINK
if (netif_carrier_ok(dev))
printk(KERN_ERR "hdlc_set_carrier_on(): already on\n");
#endif
netif_carrier_on(dev);
+#endif
}
@@ -94,11 +96,13 @@ static void __hdlc_set_carrier_off(struct net_device *dev)
if (hdlc->proto.stop)
return hdlc->proto.stop(dev);
+#if 0
#ifdef DEBUG_LINK
if (!netif_carrier_ok(dev))
printk(KERN_ERR "hdlc_set_carrier_off(): already off\n");
#endif
netif_carrier_off(dev);
+#endif
}
@@ -294,8 +298,10 @@ int register_hdlc_device(struct net_device *dev)
if (result != 0)
return -EIO;
+#if 0
if (netif_carrier_ok(dev))
netif_carrier_off(dev); /* no carrier until DCD goes up */
+#endif
return 0;
}
diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c
index 7c2cf2e..032c0f8 100644
--- a/drivers/net/wan/sdladrv.c
+++ b/drivers/net/wan/sdladrv.c
@@ -1994,7 +1994,7 @@ static int detect_s514 (sdlahw_t* hw)
modname, hw->irq);
/* map the physical PCI memory to virtual memory */
- (void *)hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr,
+ hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr,
(unsigned long)MAX_SIZEOF_S514_MEMORY);
/* map the physical control register memory to virtual memory */
hw->vector = (unsigned long)ioremap(
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 7187958..00e5516 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -330,7 +330,7 @@ config PCI_HERMES
config ATMEL
tristate "Atmel at76c50x chipset 802.11b support"
- depends on NET_RADIO && EXPERIMENTAL
+ depends on NET_RADIO
select FW_LOADER
select CRC32
---help---
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index a3e2352..5e53c52 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -72,7 +72,7 @@
#include "atmel.h"
#define DRIVER_MAJOR 0
-#define DRIVER_MINOR 96
+#define DRIVER_MINOR 98
MODULE_AUTHOR("Simon Kelley");
MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
@@ -1504,7 +1504,7 @@ static int atmel_read_proc(char *page, char **start, off_t off,
return len;
}
-struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWType fw_type,
+struct net_device *init_atmel_card( unsigned short irq, unsigned long port, const AtmelFWType fw_type,
struct device *sys_dev, int (*card_present)(void *), void *card)
{
struct net_device *dev;
@@ -1605,8 +1605,8 @@ struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWT
goto err_out_free;
}
- if (priv->bus_type == BUS_TYPE_PCI &&
- !request_region( dev->base_addr, 64, dev->name )) {
+ if (!request_region(dev->base_addr, 32,
+ priv->bus_type == BUS_TYPE_PCCARD ? "atmel_cs" : "atmel_pci")) {
goto err_out_irq;
}
@@ -1622,15 +1622,16 @@ struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWT
create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);
- printk(KERN_INFO "%s: Atmel at76c50x wireless. Version %d.%d simon@thekelleys.org.uk\n",
- dev->name, DRIVER_MAJOR, DRIVER_MINOR);
+ printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+ dev->name, DRIVER_MAJOR, DRIVER_MINOR,
+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
SET_MODULE_OWNER(dev);
return dev;
err_out_res:
- if (priv->bus_type == BUS_TYPE_PCI)
- release_region( dev->base_addr, 64 );
+ release_region( dev->base_addr, 32);
err_out_irq:
free_irq(dev->irq, dev);
err_out_free:
@@ -1640,7 +1641,7 @@ struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWT
EXPORT_SYMBOL(init_atmel_card);
-void stop_atmel_card(struct net_device *dev, int freeres)
+void stop_atmel_card(struct net_device *dev)
{
struct atmel_private *priv = netdev_priv(dev);
@@ -1654,10 +1655,7 @@ void stop_atmel_card(struct net_device *dev, int freeres)
remove_proc_entry("driver/atmel", NULL);
free_irq(dev->irq, dev);
kfree(priv->firmware);
- if (freeres) {
- /* PCMCIA frees this stuff, so only for PCI */
- release_region(dev->base_addr, 64);
- }
+ release_region(dev->base_addr, 32);
free_netdev(dev);
}
@@ -1810,9 +1808,9 @@ static int atmel_set_encode(struct net_device *dev,
}
if(dwrq->flags & IW_ENCODE_RESTRICTED)
priv->exclude_unencrypted = 1;
- if(dwrq->flags & IW_ENCODE_OPEN)
+ if(dwrq->flags & IW_ENCODE_OPEN)
priv->exclude_unencrypted = 0;
-
+
return -EINPROGRESS; /* Call commit handler */
}
@@ -1827,11 +1825,12 @@ static int atmel_get_encode(struct net_device *dev,
if (!priv->wep_is_on)
dwrq->flags = IW_ENCODE_DISABLED;
- else if (priv->exclude_unencrypted)
- dwrq->flags = IW_ENCODE_RESTRICTED;
- else
- dwrq->flags = IW_ENCODE_OPEN;
-
+ else {
+ if (priv->exclude_unencrypted)
+ dwrq->flags = IW_ENCODE_RESTRICTED;
+ else
+ dwrq->flags = IW_ENCODE_OPEN;
+ }
/* Which key do we want ? -1 -> tx index */
if (index < 0 || index >= 4)
index = priv->default_key;
@@ -2645,8 +2644,8 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c
}
}
-
-static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
+
+static void send_authentication_request(struct atmel_private *priv, u16 system, u8 *challenge, int challenge_len)
{
struct ieee80211_hdr_4addr header;
struct auth_body auth;
@@ -2658,14 +2657,11 @@ static void send_authentication_request(struct atmel_private *priv, u8 *challeng
memcpy(header.addr2, priv->dev->dev_addr, 6);
memcpy(header.addr3, priv->CurrentBSSID, 6);
- if (priv->wep_is_on) {
- auth.alg = cpu_to_le16(C80211_MGMT_AAN_SHAREDKEY);
+ if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
/* no WEP for authentication frames with TrSeqNo 1 */
- if (priv->CurrentAuthentTransactionSeqNum != 1)
- header.frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
- } else {
- auth.alg = cpu_to_le16(C80211_MGMT_AAN_OPENSYSTEM);
- }
+ header.frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+
+ auth.alg = cpu_to_le16(system);
auth.status = 0;
auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
@@ -2834,6 +2830,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
struct auth_body *auth = (struct auth_body *)priv->rx_buf;
u16 status = le16_to_cpu(auth->status);
u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
+ u16 system = le16_to_cpu(auth->alg);
if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) {
/* no WEP */
@@ -2855,7 +2852,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
if (trans_seq_no == 0x0002 &&
auth->el_id == C80211_MGMT_ElementID_ChallengeText) {
- send_authentication_request(priv, auth->chall_text, auth->chall_text_len);
+ send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
return;
}
@@ -2872,14 +2869,20 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
}
}
- if (status == C80211_MGMT_SC_AuthAlgNotSupported && priv->connect_to_any_BSS) {
- int bss_index;
-
- priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
-
- if ((bss_index = retrieve_bss(priv)) != -1) {
- atmel_join_bss(priv, bss_index);
- return;
+ if (status == C80211_MGMT_SC_AuthAlgNotSupported) {
+ /* Do opensystem first, then try sharedkey */
+ if (system == C80211_MGMT_AAN_OPENSYSTEM) {
+ priv->CurrentAuthentTransactionSeqNum = 0x001;
+ send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
+ } else if (priv->connect_to_any_BSS) {
+ int bss_index;
+
+ priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
+
+ if ((bss_index = retrieve_bss(priv)) != -1) {
+ atmel_join_bss(priv, bss_index);
+ return;
+ }
}
}
@@ -3205,7 +3208,7 @@ static void atmel_management_timer(u_long a)
priv->AuthenticationRequestRetryCnt++;
priv->CurrentAuthentTransactionSeqNum = 0x0001;
mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
- send_authentication_request(priv, NULL, 0);
+ send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0);
}
break;
@@ -3312,7 +3315,7 @@ static void atmel_command_irq(struct atmel_private *priv)
mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
priv->CurrentAuthentTransactionSeqNum = 0x0001;
- send_authentication_request(priv, NULL, 0);
+ send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
}
return;
}
@@ -3482,11 +3485,6 @@ static int probe_atmel_card(struct net_device *dev)
printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
memcpy(dev->dev_addr, default_mac, 6);
}
- printk(KERN_INFO "%s: MAC address %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
- dev->name,
- dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
- dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
-
}
return rc;
diff --git a/drivers/net/wireless/atmel.h b/drivers/net/wireless/atmel.h
index 825000e..b9b3e5b 100644
--- a/drivers/net/wireless/atmel.h
+++ b/drivers/net/wireless/atmel.h
@@ -35,9 +35,9 @@ typedef enum {
ATMEL_FW_TYPE_506
} AtmelFWType;
-struct net_device *init_atmel_card(unsigned short, int, const AtmelFWType, struct device *,
+struct net_device *init_atmel_card(unsigned short, unsigned long, const AtmelFWType, struct device *,
int (*present_func)(void *), void * );
-void stop_atmel_card( struct net_device *, int );
+void stop_atmel_card( struct net_device *);
int atmel_open( struct net_device * );
#endif
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 1bd1314..17d1fd9 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -63,6 +63,7 @@
be present but disabled -- but it can then be enabled for specific
modules at load time with a 'pc_debug=#' option to insmod.
*/
+
#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0);
@@ -285,41 +286,6 @@ static int card_present(void *arg)
return 0;
}
-/* list of cards we know about and their firmware requirements.
- Go either by Manfid or version strings.
- Cards not in this list will need a firmware parameter to the module
- in all probability. Note that the SMC 2632 V2 and V3 have the same
- manfids, so we ignore those and use the version1 strings. */
-
-static struct {
- int manf, card;
- char *ver1;
- AtmelFWType firmware;
- char *name;
-} card_table[] = {
- { 0, 0, "WLAN/802.11b PC CARD", ATMEL_FW_TYPE_502D, "Actiontec 802CAT1" },
- { 0, 0, "ATMEL/AT76C502AR", ATMEL_FW_TYPE_502, "NoName-RFMD" },
- { 0, 0, "ATMEL/AT76C502AR_D", ATMEL_FW_TYPE_502D, "NoName-revD" },
- { 0, 0, "ATMEL/AT76C502AR_E", ATMEL_FW_TYPE_502E, "NoName-revE" },
- { 0, 0, "ATMEL/AT76C504", ATMEL_FW_TYPE_504, "NoName-504" },
- { 0, 0, "ATMEL/AT76C504A", ATMEL_FW_TYPE_504A_2958, "NoName-504a-2958" },
- { 0, 0, "ATMEL/AT76C504_R", ATMEL_FW_TYPE_504_2958, "NoName-504-2958" },
- { MANFID_3COM, 0x0620, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRWE62092B" },
- { MANFID_3COM, 0x0696, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRSHPW196" },
- { 0, 0, "SMC/2632W-V2", ATMEL_FW_TYPE_502, "SMC 2632W-V2" },
- { 0, 0, "SMC/2632W", ATMEL_FW_TYPE_502D, "SMC 2632W-V3" },
- { 0xd601, 0x0007, NULL, ATMEL_FW_TYPE_502, "Sitecom WLAN-011" },
- { 0x01bf, 0x3302, NULL, ATMEL_FW_TYPE_502E, "Belkin F5D6020-V2" },
- { 0, 0, "BT/Voyager 1020 Laptop Adapter", ATMEL_FW_TYPE_502, "BT Voyager 1020" },
- { 0, 0, "IEEE 802.11b/Wireless LAN PC Card", ATMEL_FW_TYPE_502, "Siemens Gigaset PC Card II" },
- { 0, 0, "IEEE 802.11b/Wireless LAN Card S", ATMEL_FW_TYPE_504_2958, "Siemens Gigaset PC Card II" },
- { 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", ATMEL_FW_TYPE_502E, "CNet CNWLC-811ARL" },
- { 0, 0, "Wireless/PC_CARD", ATMEL_FW_TYPE_502D, "Planet WL-3552" },
- { 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", ATMEL_FW_TYPE_502, "OEM 11Mbps WLAN PCMCIA Card" },
- { 0, 0, "11WAVE/11WP611AL-E", ATMEL_FW_TYPE_502E, "11WAVE WaveBuddy" },
- { 0, 0, "LG/LW2100N", ATMEL_FW_TYPE_502E, "LG LW2100N 11Mbps WLAN PCMCIA Card" },
-};
-
static void atmel_config(dev_link_t *link)
{
client_handle_t handle;
@@ -328,10 +294,11 @@ static void atmel_config(dev_link_t *link)
local_info_t *dev;
int last_fn, last_ret;
u_char buf[64];
- int card_index = -1, done = 0;
-
+ struct pcmcia_device_id *did;
+
handle = link->handle;
dev = link->priv;
+ did = handle_to_dev(handle).driver_data;
DEBUG(0, "atmel_config(0x%p)\n", link);
@@ -340,59 +307,6 @@ static void atmel_config(dev_link_t *link)
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_MANFID;
- if (pcmcia_get_first_tuple(handle, &tuple) == 0) {
- int i;
- cistpl_manfid_t *manfid;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
- manfid = &(parse.manfid);
- for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
- if (!card_table[i].ver1 &&
- manfid->manf == card_table[i].manf &&
- manfid->card == card_table[i].card) {
- card_index = i;
- done = 1;
- }
- }
- }
-
- tuple.DesiredTuple = CISTPL_VERS_1;
- if (!done && (pcmcia_get_first_tuple(handle, &tuple) == 0)) {
- int i, j, k;
- cistpl_vers_1_t *ver1;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
- ver1 = &(parse.version_1);
-
- for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
- for (j = 0; j < ver1->ns; j++) {
- char *p = card_table[i].ver1;
- char *q = &ver1->str[ver1->ofs[j]];
- if (!p)
- goto mismatch;
- for (k = 0; k < j; k++) {
- while ((*p != '\0') && (*p != '/')) p++;
- if (*p == '\0') {
- if (*q != '\0')
- goto mismatch;
- } else {
- p++;
- }
- }
- while((*q != '\0') && (*p != '\0') &&
- (*p != '/') && (*p == *q)) p++, q++;
- if (((*p != '\0') && *p != '/') || *q != '\0')
- goto mismatch;
- }
- card_index = i;
- break; /* done */
-
- mismatch:
- j = 0; /* dummy stmt to shut up compiler */
- }
- }
-
/*
This reads the card's CONFIG tuple to find its configuration
registers.
@@ -509,12 +423,13 @@ static void atmel_config(dev_link_t *link)
((local_info_t*)link->priv)->eth_dev =
init_atmel_card(link->irq.AssignedIRQ,
link->io.BasePort1,
- card_index == -1 ? ATMEL_FW_TYPE_NONE : card_table[card_index].firmware,
+ did ? did->driver_info : ATMEL_FW_TYPE_NONE,
&handle_to_dev(handle),
card_present,
link);
if (!((local_info_t*)link->priv)->eth_dev)
- goto cs_failed;
+ goto cs_failed;
+
/*
At this point, the dev_node_t structure(s) need to be
@@ -523,26 +438,7 @@ static void atmel_config(dev_link_t *link)
strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
dev->node.major = dev->node.minor = 0;
link->dev = &dev->node;
-
- /* Finally, report what we've done */
- printk(KERN_INFO "%s: %s%sindex 0x%02x: Vcc %d.%d",
- dev->node.dev_name,
- card_index == -1 ? "" : card_table[card_index].name,
- card_index == -1 ? "" : " ",
- link->conf.ConfigIndex,
- link->conf.Vcc/10, link->conf.Vcc%10);
- if (link->conf.Vpp1)
- printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
- if (link->conf.Attributes & CONF_ENABLE_IRQ)
- printk(", irq %d", link->irq.AssignedIRQ);
- if (link->io.NumPorts1)
- printk(", io 0x%04x-0x%04x", link->io.BasePort1,
- link->io.BasePort1+link->io.NumPorts1-1);
- if (link->io.NumPorts2)
- printk(" & 0x%04x-0x%04x", link->io.BasePort2,
- link->io.BasePort2+link->io.NumPorts2-1);
- printk("\n");
-
+
link->state &= ~DEV_CONFIG_PENDING;
return;
@@ -569,7 +465,7 @@ static void atmel_release(dev_link_t *link)
link->dev = NULL;
if (dev)
- stop_atmel_card(dev, 0);
+ stop_atmel_card(dev);
((local_info_t*)link->priv)->eth_dev = NULL;
/* Don't bother checking to see if these succeed or not */
@@ -637,25 +533,47 @@ static int atmel_event(event_t event, int priority,
} /* atmel_event */
/*====================================================================*/
+/* We use the driver_info field to store the correct firmware type for a card. */
+
+#define PCMCIA_DEVICE_MANF_CARD_INFO(manf, card, info) { \
+ .match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \
+ PCMCIA_DEV_ID_MATCH_CARD_ID, \
+ .manf_id = (manf), \
+ .card_id = (card), \
+ .driver_info = (kernel_ulong_t)(info), }
+
+#define PCMCIA_DEVICE_PROD_ID12_INFO(v1, v2, vh1, vh2, info) { \
+ .match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+ PCMCIA_DEV_ID_MATCH_PROD_ID2, \
+ .prod_id = { (v1), (v2), NULL, NULL }, \
+ .prod_id_hash = { (vh1), (vh2), 0, 0 }, \
+ .driver_info = (kernel_ulong_t)(info), }
+
static struct pcmcia_device_id atmel_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0620),
- PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0696),
- PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x3302),
- PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0007),
- PCMCIA_DEVICE_PROD_ID12("11WAVE", "11WP611AL-E", 0x9eb2da1f, 0xc9a0d3f9),
- PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C502AR", 0xabda4164, 0x41b37e1f),
- PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C504", 0xabda4164, 0x5040670a),
- PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C504A", 0xabda4164, 0xe15ed87f),
- PCMCIA_DEVICE_PROD_ID12("BT", "Voyager 1020 Laptop Adapter", 0xae49b86a, 0x1e957cd5),
- PCMCIA_DEVICE_PROD_ID12("CNet", "CNWLC 11Mbps Wireless PC Card V-5", 0xbc477dde, 0x502fae6b),
- PCMCIA_DEVICE_PROD_ID12("IEEE 802.11b", "Wireless LAN PC Card", 0x5b878724, 0x122f1df6),
- PCMCIA_DEVICE_PROD_ID12("OEM", "11Mbps Wireless LAN PC Card V-3", 0xfea54c90, 0x1c5b0f68),
- PCMCIA_DEVICE_PROD_ID12("SMC", "2632W", 0xc4f8b18b, 0x30f38774),
- PCMCIA_DEVICE_PROD_ID12("SMC", "2632W-V2", 0xc4f8b18b, 0x172d1377),
- PCMCIA_DEVICE_PROD_ID12("Wireless", "PC", 0xa407ecdd, 0x556e4d7e),
- PCMCIA_DEVICE_PROD_ID12("WLAN", "802.11b PC CARD", 0x575c516c, 0xb1f6dbc4),
+ PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0620, ATMEL_FW_TYPE_502_3COM),
+ PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0696, ATMEL_FW_TYPE_502_3COM),
+ PCMCIA_DEVICE_MANF_CARD_INFO(0x01bf, 0x3302, ATMEL_FW_TYPE_502E),
+ PCMCIA_DEVICE_MANF_CARD_INFO(0xd601, 0x0007, ATMEL_FW_TYPE_502),
+ PCMCIA_DEVICE_PROD_ID12_INFO("11WAVE", "11WP611AL-E", 0x9eb2da1f, 0xc9a0d3f9, ATMEL_FW_TYPE_502E),
+ PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR", 0xabda4164, 0x41b37e1f, ATMEL_FW_TYPE_502),
+ PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR_D", 0xabda4164, 0x3675d704, ATMEL_FW_TYPE_502D),
+ PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR_E", 0xabda4164, 0x4172e792, ATMEL_FW_TYPE_502E),
+ PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504_R", 0xabda4164, 0x917f3d72, ATMEL_FW_TYPE_504_2958),
+ PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504", 0xabda4164, 0x5040670a, ATMEL_FW_TYPE_504),
+ PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504A", 0xabda4164, 0xe15ed87f, ATMEL_FW_TYPE_504A_2958),
+ PCMCIA_DEVICE_PROD_ID12_INFO("BT", "Voyager 1020 Laptop Adapter", 0xae49b86a, 0x1e957cd5, ATMEL_FW_TYPE_502),
+ PCMCIA_DEVICE_PROD_ID12_INFO("CNet", "CNWLC 11Mbps Wireless PC Card V-5", 0xbc477dde, 0x502fae6b, ATMEL_FW_TYPE_502E),
+ PCMCIA_DEVICE_PROD_ID12_INFO("IEEE 802.11b", "Wireless LAN PC Card", 0x5b878724, 0x122f1df6, ATMEL_FW_TYPE_502),
+ PCMCIA_DEVICE_PROD_ID12_INFO("IEEE 802.11b", "Wireless LAN Card S", 0x5b878724, 0x5fba533a, ATMEL_FW_TYPE_504_2958),
+ PCMCIA_DEVICE_PROD_ID12_INFO("OEM", "11Mbps Wireless LAN PC Card V-3", 0xfea54c90, 0x1c5b0f68, ATMEL_FW_TYPE_502),
+ PCMCIA_DEVICE_PROD_ID12_INFO("SMC", "2632W", 0xc4f8b18b, 0x30f38774, ATMEL_FW_TYPE_502D),
+ PCMCIA_DEVICE_PROD_ID12_INFO("SMC", "2632W-V2", 0xc4f8b18b, 0x172d1377, ATMEL_FW_TYPE_502),
+ PCMCIA_DEVICE_PROD_ID12_INFO("Wireless", "PC_CARD", 0xa407ecdd, 0x119f6314, ATMEL_FW_TYPE_502D),
+ PCMCIA_DEVICE_PROD_ID12_INFO("WLAN", "802.11b PC CARD", 0x575c516c, 0xb1f6dbc4, ATMEL_FW_TYPE_502D),
+ PCMCIA_DEVICE_PROD_ID12_INFO("LG", "LW2100N", 0xb474d43a, 0x6b1fec94, ATMEL_FW_TYPE_502E),
PCMCIA_DEVICE_NULL
};
+
MODULE_DEVICE_TABLE(pcmcia, atmel_ids);
static struct pcmcia_driver atmel_driver = {
diff --git a/drivers/net/wireless/atmel_pci.c b/drivers/net/wireless/atmel_pci.c
index 2eb00a9..a61b3bc 100644
--- a/drivers/net/wireless/atmel_pci.c
+++ b/drivers/net/wireless/atmel_pci.c
@@ -72,7 +72,7 @@ static int __devinit atmel_pci_probe(struct pci_dev *pdev,
static void __devexit atmel_pci_remove(struct pci_dev *pdev)
{
- stop_atmel_card(pci_get_drvdata(pdev), 1);
+ stop_atmel_card(pci_get_drvdata(pdev));
}
static int __init atmel_init_module(void)
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
index 579480d..346c6fe 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/hermes.c
@@ -398,7 +398,7 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
*
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/
-int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
+int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
u16 id, u16 offset)
{
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -424,7 +424,7 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
*
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/
-int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
+int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
u16 id, u16 offset)
{
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -450,7 +450,7 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
*
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/
-int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, unsigned len,
+int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, int len,
u16 id, u16 offset)
{
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index a6bd472..7644f72 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -372,12 +372,12 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
struct hermes_response *resp);
int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
-int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
+int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
u16 id, u16 offset);
-int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
+int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
u16 id, u16 offset);
int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf,
- unsigned data_len, unsigned len, u16 id, u16 offset);
+ unsigned data_len, int len, u16 id, u16 offset);
int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
u16 *length, void *buf);
int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
diff --git a/drivers/net/wireless/i82593.h b/drivers/net/wireless/i82593.h
index 33acb8a..afac5c7 100644
--- a/drivers/net/wireless/i82593.h
+++ b/drivers/net/wireless/i82593.h
@@ -7,11 +7,16 @@
*
* Copyright 1994, Anders Klemets <klemets@it.kth.se>
*
- * This software may be freely distributed for noncommercial purposes
- * as long as this notice is retained.
- *
* HISTORY
* i82593.h,v
+ * Revision 1.4 2005/11/4 09:15:00 baroniunas
+ * Modified copyright with permission of author as follows:
+ *
+ * "If I82539.H is the only file with my copyright statement
+ * that is included in the Source Forge project, then you have
+ * my approval to change the copyright statement to be a GPL
+ * license, in the way you proposed on October 10."
+ *
* Revision 1.1 1996/07/17 15:23:12 root
* Initial revision
*
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index a2e6214..77d2a21 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -6344,7 +6344,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
dev->ethtool_ops = &ipw2100_ethtool_ops;
dev->tx_timeout = ipw2100_tx_timeout;
dev->wireless_handlers = &ipw2100_wx_handler_def;
- dev->get_wireless_stats = ipw2100_wx_wireless_stats;
+ priv->wireless_data.ieee80211 = priv->ieee;
+ dev->wireless_data = &priv->wireless_data;
dev->set_mac_address = ipw2100_set_address;
dev->watchdog_timeo = 3 * HZ;
dev->irq = 0;
@@ -7178,6 +7179,11 @@ static int ipw2100_wx_get_range(struct net_device *dev,
}
range->num_frequency = val;
+ /* Event capability (kernel + driver) */
+ range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
+ IW_EVENT_CAPA_MASK(SIOCGIWAP));
+ range->event_capa[1] = IW_EVENT_CAPA_K_1;
+
IPW_DEBUG_WX("GET Range\n");
return 0;
@@ -8446,16 +8452,6 @@ static iw_handler ipw2100_private_handler[] = {
#endif /* CONFIG_IPW2100_MONITOR */
};
-static struct iw_handler_def ipw2100_wx_handler_def = {
- .standard = ipw2100_wx_handlers,
- .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
- .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
- .num_private_args = sizeof(ipw2100_private_args) /
- sizeof(struct iw_priv_args),
- .private = (iw_handler *) ipw2100_private_handler,
- .private_args = (struct iw_priv_args *)ipw2100_private_args,
-};
-
/*
* Get wireless statistics.
* Called by /proc/net/wireless
@@ -8597,6 +8593,17 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
return (struct iw_statistics *)NULL;
}
+static struct iw_handler_def ipw2100_wx_handler_def = {
+ .standard = ipw2100_wx_handlers,
+ .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
+ .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
+ .num_private_args = sizeof(ipw2100_private_args) /
+ sizeof(struct iw_priv_args),
+ .private = (iw_handler *) ipw2100_private_handler,
+ .private_args = (struct iw_priv_args *)ipw2100_private_args,
+ .get_wireless_stats = ipw2100_wx_wireless_stats,
+};
+
static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
{
union iwreq_data wrqu;
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 140fdf2..7c65b10 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -571,6 +571,8 @@ struct ipw2100_priv {
struct net_device *net_dev;
struct iw_statistics wstats;
+ struct iw_public_data wireless_data;
+
struct tasklet_struct irq_tasklet;
struct workqueue_struct *workqueue;
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index b0d195d..5e7c7e9 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1110,8 +1110,7 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
error->elem_len = elem_len;
error->log_len = log_len;
error->elem = (struct ipw_error_elem *)error->payload;
- error->log = (struct ipw_event *)(error->elem +
- (sizeof(*error->elem) * elem_len));
+ error->log = (struct ipw_event *)(error->elem + elem_len);
ipw_capture_event_log(priv, log_len, error->log);
@@ -8926,6 +8925,10 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
struct ipw_scan_request_ext scan;
int err = 0, scan_type;
+ if (!(priv->status & STATUS_INIT) ||
+ (priv->status & STATUS_EXIT_PENDING))
+ return 0;
+
down(&priv->sem);
if (priv->status & STATUS_RF_KILL_MASK) {
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index 109a96d..23deee6 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -164,12 +164,12 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
/* assert the Wakeup interrupt in the Device Interrupt Register */
isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_WAKEUP,
ISL38XX_DEV_INT_REG);
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
udelay(ISL38XX_WRITEIO_DELAY);
/* perform another read on the Device Status Register */
reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
-
-#if VERBOSE > SHOW_ERROR_MESSAGES
do_gettimeofday(&current_time);
DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n",
current_time.tv_sec, (long)current_time.tv_usec, reg);
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index a39fbfe..19657ef 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -700,6 +700,28 @@ static unsigned int iosapic_startup_irq(unsigned int irq)
return 0;
}
+#ifdef CONFIG_SMP
+static void iosapic_set_affinity_irq(unsigned int irq, cpumask_t dest)
+{
+ struct vector_info *vi = iosapic_get_vector(irq);
+ u32 d0, d1, dummy_d0;
+ unsigned long flags;
+
+ if (cpu_check_affinity(irq, &dest))
+ return;
+
+ vi->txn_addr = txn_affinity_addr(irq, first_cpu(dest));
+
+ spin_lock_irqsave(&iosapic_lock, flags);
+ /* d1 contains the destination CPU, so only want to set that
+ * entry */
+ iosapic_rd_irt_entry(vi, &d0, &d1);
+ iosapic_set_irt_data(vi, &dummy_d0, &d1);
+ iosapic_wr_irt_entry(vi, d0, d1);
+ spin_unlock_irqrestore(&iosapic_lock, flags);
+}
+#endif
+
static struct hw_interrupt_type iosapic_interrupt_type = {
.typename = "IO-SAPIC-level",
.startup = iosapic_startup_irq,
@@ -708,7 +730,9 @@ static struct hw_interrupt_type iosapic_interrupt_type = {
.disable = iosapic_disable_irq,
.ack = no_ack_irq,
.end = iosapic_end_irq,
-// .set_affinity = iosapic_set_affinity_irq,
+#ifdef CONFIG_SMP
+ .set_affinity = iosapic_set_affinity_irq,
+#endif
};
int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index bab3bca..d14888e 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -24,6 +24,9 @@
* Major changes to get basic interrupt infrastructure working to
* hopefully be able to support all SuperIO devices. Currently
* works with serial. -- John Marvin <jsm@fc.hp.com>
+ *
+ * Converted superio_init() to be a PCI_FIXUP_FINAL callee.
+ * -- Kyle McMartin <kyle@parisc-linux.org>
*/
@@ -141,10 +144,10 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
}
/* Initialize Super I/O device */
-
-static void __devinit
-superio_init(struct superio_device *sio)
+static void
+superio_init(struct pci_dev *pcidev)
{
+ struct superio_device *sio = &sio_dev;
struct pci_dev *pdev = sio->lio_pdev;
u16 word;
@@ -160,8 +163,8 @@ superio_init(struct superio_device *sio)
/* ...then properly fixup the USB to point at suckyio PIC */
sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);
- printk (KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
- pci_name(pdev),pdev->irq);
+ printk(KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
+ pci_name(pdev), pdev->irq);
pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);
sio->sp1_base &= ~1;
@@ -274,7 +277,7 @@ superio_init(struct superio_device *sio)
sio->suckyio_irq_enabled = 1;
}
-
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO, superio_init);
static void superio_disable_irq(unsigned int irq)
{
@@ -452,8 +455,10 @@ static void superio_fixup_pci(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, superio_fixup_pci);
-static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int __devinit
+superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
+ struct superio_device *sio = &sio_dev;
/*
** superio_probe(00:0e.0) ven 0x100b dev 0x2 sv 0x0 sd 0x0 class 0x1018a
@@ -466,7 +471,8 @@ static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_
dev->subsystem_vendor, dev->subsystem_device,
dev->class);
- superio_init(&sio_dev);
+ if (!sio->suckyio_irq_enabled)
+ BUG(); /* Enabled by PCI_FIXUP_FINAL */
if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) { /* Function 1 */
superio_parport_init();
@@ -481,19 +487,21 @@ static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_
DBG_INIT("superio_probe: WTF? Fire Extinguisher?\n");
}
- /* Let appropriate other driver claim this device. */
+ /* Let appropriate other driver claim this device. */
return -ENODEV;
}
static struct pci_device_id superio_tbl[] = {
- { PCI_VENDOR_ID_NS, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) },
{ 0, }
};
static struct pci_driver superio_driver = {
- .name = "SuperIO",
- .id_table = superio_tbl,
- .probe = superio_probe,
+ .name = "SuperIO",
+ .id_table = superio_tbl,
+ .probe = superio_probe,
};
static int __init superio_modinit(void)
@@ -506,6 +514,5 @@ static void __exit superio_exit(void)
pci_unregister_driver(&superio_driver);
}
-
module_init(superio_modinit);
module_exit(superio_exit);
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 2a42add..ea16805 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -2,6 +2,8 @@
#include <linux/module.h>
#include <linux/ioport.h>
+#include "pci.h"
+
/*
* This interrupt-safe spinlock protects all accesses to PCI
* configuration space.
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 061ead2..c42b68d 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -32,8 +32,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
-#include <asm/semaphore.h>
-#include <asm/io.h>
#include <linux/pcieport_if.h>
#include "pci_hotplug.h"
@@ -42,6 +40,7 @@
extern int pciehp_poll_mode;
extern int pciehp_poll_time;
extern int pciehp_debug;
+extern int pciehp_force;
/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
@@ -49,39 +48,20 @@ extern int pciehp_debug;
#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
-struct pci_func {
- struct pci_func *next;
- u8 bus;
- u8 device;
- u8 function;
- u8 is_a_board;
- u16 status;
- u8 configured;
- u8 switch_save;
- u8 presence_save;
- u32 base_length[0x06];
- u8 base_type[0x06];
- u16 reserved2;
- u32 config_space[0x20];
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
- struct pci_dev* pci_dev;
+struct hotplug_params {
+ u8 cache_line_size;
+ u8 latency_timer;
+ u8 enable_serr;
+ u8 enable_perr;
};
struct slot {
struct slot *next;
u8 bus;
u8 device;
+ u16 status;
u32 number;
- u8 is_a_board;
- u8 configured;
u8 state;
- u8 switch_save;
- u8 presence_save;
- u32 capabilities;
- u16 reserved2;
struct timer_list task_event;
u8 hp_slot;
struct controller *ctrl;
@@ -90,42 +70,47 @@ struct slot {
struct list_head slot_list;
};
-struct pci_resource {
- struct pci_resource * next;
- u32 base;
- u32 length;
-};
-
struct event_info {
u32 event_type;
u8 hp_slot;
};
+typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
+
+struct php_ctlr_state_s {
+ struct php_ctlr_state_s *pnext;
+ struct pci_dev *pci_dev;
+ unsigned int irq;
+ unsigned long flags; /* spinlock's */
+ u32 slot_device_offset;
+ u32 num_slots;
+ struct timer_list int_poll_timer; /* Added for poll event */
+ php_intr_callback_t attention_button_callback;
+ php_intr_callback_t switch_change_callback;
+ php_intr_callback_t presence_change_callback;
+ php_intr_callback_t power_fault_callback;
+ void *callback_instance_id;
+ struct ctrl_reg *creg; /* Ptr to controller register space */
+};
+
+#define MAX_EVENTS 10
struct controller {
struct controller *next;
struct semaphore crit_sect; /* critical section semaphore */
- void *hpc_ctlr_handle; /* HPC controller handle */
+ struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
struct pci_dev *pci_dev;
struct pci_bus *pci_bus;
- struct event_info event_queue[10];
+ struct event_info event_queue[MAX_EVENTS];
struct slot *slot;
struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */
u8 next_event;
- u8 seg;
u8 bus;
u8 device;
u8 function;
- u8 rev;
u8 slot_device_offset;
- u8 add_support;
- enum pci_bus_speed speed;
u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */
u8 slot_bus; /* Bus where the slots handled by this controller sit */
u8 ctrlcap;
@@ -133,20 +118,6 @@ struct controller {
u8 cap_base;
};
-struct irq_mapping {
- u8 barber_pole;
- u8 valid_INT;
- u8 interrupt[4];
-};
-
-struct resource_lists {
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
- struct irq_mapping *irqs;
-};
-
#define INT_BUTTON_IGNORE 0
#define INT_PRESENCE_ON 1
#define INT_PRESENCE_OFF 2
@@ -200,21 +171,14 @@ struct resource_lists {
* error Messages
*/
#define msg_initialization_err "Initialization failure, error=%d\n"
-#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
-#define msg_HPC_non_pcie "The PCI hot plug controller is not supported by this driver.\n"
-#define msg_HPC_not_supported "This system is not supported by this version of pciephd module. Upgrade to a newer version of pciehpd\n"
-#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
/* controller functions */
-extern int pciehprm_find_available_resources (struct controller *ctrl);
extern int pciehp_event_start_thread (void);
extern void pciehp_event_stop_thread (void);
-extern struct pci_func *pciehp_slot_create (unsigned char busnumber);
-extern struct pci_func *pciehp_slot_find (unsigned char bus, unsigned char device, unsigned char index);
extern int pciehp_enable_slot (struct slot *slot);
extern int pciehp_disable_slot (struct slot *slot);
@@ -224,25 +188,17 @@ extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id);
extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id);
/* extern void long_delay (int delay); */
-/* resource functions */
-extern int pciehp_resource_sort_and_combine (struct pci_resource **head);
-
/* pci functions */
-extern int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
-/*extern int pciehp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/
-extern int pciehp_save_config (struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
-extern int pciehp_save_used_resources (struct controller *ctrl, struct pci_func * func, int flag);
-extern int pciehp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot);
-extern void pciehp_destroy_board_resources (struct pci_func * func);
-extern int pciehp_return_board_resources (struct pci_func * func, struct resource_lists * resources);
-extern void pciehp_destroy_resource_list (struct resource_lists * resources);
-extern int pciehp_configure_device (struct controller* ctrl, struct pci_func* func);
-extern int pciehp_unconfigure_device (struct pci_func* func);
+extern int pciehp_configure_device (struct slot *p_slot);
+extern int pciehp_unconfigure_device (struct slot *p_slot);
+extern int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev);
+extern void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
+ struct hotplug_params *hpp);
+
/* Global variables */
extern struct controller *pciehp_ctrl_list;
-extern struct pci_func *pciehp_slot_list[256];
/* Inline functions */
@@ -252,12 +208,9 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
p_slot = ctrl->slot;
- dbg("p_slot = %p\n", p_slot);
-
while (p_slot && (p_slot->device != device)) {
tmp_slot = p_slot;
p_slot = p_slot->next;
- dbg("In while loop, p_slot = %p\n", p_slot);
}
if (p_slot == NULL) {
err("ERROR: pciehp_find_slot device=0x%x\n", device);
@@ -273,7 +226,6 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
DECLARE_WAITQUEUE(wait, current);
- dbg("%s : start\n", __FUNCTION__);
add_wait_queue(&ctrl->queue, &wait);
if (!pciehp_poll_mode)
/* Sleep for up to 1 second */
@@ -285,19 +237,9 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
if (signal_pending(current))
retval = -EINTR;
- dbg("%s : end\n", __FUNCTION__);
return retval;
}
-/* Puts node back in the resource list pointed to by head */
-static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
-{
- if (!node || !head)
- return;
- node->next = *head;
- *head = node;
-}
-
#define SLOT_NAME_SIZE 10
static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
@@ -311,14 +253,7 @@ enum php_ctlr_type {
ACPI
};
-typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id);
-
-int pcie_init(struct controller *ctrl, struct pcie_device *dev,
- php_intr_callback_t attention_button_callback,
- php_intr_callback_t switch_change_callback,
- php_intr_callback_t presence_change_callback,
- php_intr_callback_t power_fault_callback);
-
+int pcie_init(struct controller *ctrl, struct pcie_device *dev);
/* This has no meaning for PCI Express, as there is only 1 slot per port */
int pcie_get_ctlr_slot_config(struct controller *ctrl,
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index cafc7ea..8df7048 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -27,27 +27,20 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
#include <linux/pci.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
#include "pciehp.h"
-#include "pciehprm.h"
#include <linux/interrupt.h>
/* Global variables */
int pciehp_debug;
int pciehp_poll_mode;
int pciehp_poll_time;
+int pciehp_force;
struct controller *pciehp_ctrl_list;
-struct pci_func *pciehp_slot_list[256];
#define DRIVER_VERSION "0.4"
#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
@@ -60,9 +53,11 @@ MODULE_LICENSE("GPL");
module_param(pciehp_debug, bool, 0644);
module_param(pciehp_poll_mode, bool, 0644);
module_param(pciehp_poll_time, int, 0644);
+module_param(pciehp_force, bool, 0644);
MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
+MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing");
#define PCIE_MODULE_NAME "pciehp"
@@ -114,8 +109,6 @@ static int init_slots(struct controller *ctrl)
u32 slot_number;
int result = -ENOMEM;
- dbg("%s\n",__FUNCTION__);
-
number_of_slots = ctrl->num_slots;
slot_device = ctrl->slot_device_offset;
slot_number = ctrl->first_slot;
@@ -370,7 +363,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
u8 value;
struct pci_dev *pdev;
- dbg("%s: Called by hp_drv\n", __FUNCTION__);
ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl) {
err("%s : out of memory\n", __FUNCTION__);
@@ -378,22 +370,15 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
}
memset(ctrl, 0, sizeof(struct controller));
- dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid);
-
pdev = dev->port;
+ ctrl->pci_dev = pdev;
- rc = pcie_init(ctrl, dev,
- (php_intr_callback_t) pciehp_handle_attention_button,
- (php_intr_callback_t) pciehp_handle_switch_change,
- (php_intr_callback_t) pciehp_handle_presence_change,
- (php_intr_callback_t) pciehp_handle_power_fault);
+ rc = pcie_init(ctrl, dev);
if (rc) {
dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME);
goto err_out_free_ctrl;
}
- ctrl->pci_dev = pdev;
-
pci_set_drvdata(pdev, ctrl);
ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
@@ -402,7 +387,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
rc = -ENOMEM;
goto err_out_unmap_mmio_region;
}
- dbg("%s: ctrl->pci_bus %p\n", __FUNCTION__, ctrl->pci_bus);
memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
ctrl->bus = pdev->bus->number; /* ctrl bus */
ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */
@@ -424,25 +408,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
first_device_num = ctrl->slot_device_offset;
num_ctlr_slots = ctrl->num_slots;
- /* Store PCI Config Space for all devices on this bus */
- dbg("%s: Before calling pciehp_save_config, ctrl->bus %x,ctrl->slot_bus %x\n",
- __FUNCTION__,ctrl->bus, ctrl->slot_bus);
- rc = pciehp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num);
- if (rc) {
- err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
- goto err_out_free_ctrl_bus;
- }
-
- /* Get IO, memory, and IRQ resources for new devices */
- rc = pciehprm_find_available_resources(ctrl);
- ctrl->add_support = !rc;
-
- if (rc) {
- dbg("pciehprm_find_available_resources = %#x\n", rc);
- err("unable to locate PCI configuration resources for hot plug add.\n");
- goto err_out_free_ctrl_bus;
- }
-
/* Setup the slot information structures */
rc = init_slots(ctrl);
if (rc) {
@@ -451,7 +416,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
}
t_slot = pciehp_find_slot(ctrl, first_device_num);
- dbg("%s: t_slot %p\n", __FUNCTION__, t_slot);
/* Finish setting up the hot plug ctrl device */
ctrl->next_event = 0;
@@ -468,7 +432,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
down(&ctrl->crit_sect);
t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
- dbg("%s: adpater value %x\n", __FUNCTION__, value);
if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
@@ -501,7 +464,6 @@ err_out_none:
static int pcie_start_thread(void)
{
- int loop;
int retval = 0;
dbg("Initialize + Start the notification/polling mechanism \n");
@@ -512,32 +474,11 @@ static int pcie_start_thread(void)
return retval;
}
- dbg("Initialize slot lists\n");
- /* One slot list for each bus in the system */
- for (loop = 0; loop < 256; loop++) {
- pciehp_slot_list[loop] = NULL;
- }
-
return retval;
}
-static inline void __exit
-free_pciehp_res(struct pci_resource *res)
-{
- struct pci_resource *tres;
-
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-}
-
static void __exit unload_pciehpd(void)
{
- struct pci_func *next;
- struct pci_func *TempSlot;
- int loop;
struct controller *ctrl;
struct controller *tctrl;
@@ -546,11 +487,6 @@ static void __exit unload_pciehpd(void)
while (ctrl) {
cleanup_slots(ctrl);
- free_pciehp_res(ctrl->io_head);
- free_pciehp_res(ctrl->mem_head);
- free_pciehp_res(ctrl->p_mem_head);
- free_pciehp_res(ctrl->bus_head);
-
kfree (ctrl->pci_bus);
ctrl->hpc_ops->release_ctlr(ctrl);
@@ -561,20 +497,6 @@ static void __exit unload_pciehpd(void)
kfree(tctrl);
}
- for (loop = 0; loop < 256; loop++) {
- next = pciehp_slot_list[loop];
- while (next != NULL) {
- free_pciehp_res(next->io_head);
- free_pciehp_res(next->mem_head);
- free_pciehp_res(next->p_mem_head);
- free_pciehp_res(next->bus_head);
-
- TempSlot = next;
- next = next->next;
- kfree(TempSlot);
- }
- }
-
/* Stop the notification mechanism */
pciehp_event_stop_thread();
@@ -639,21 +561,16 @@ static int __init pcied_init(void)
if (retval)
goto error_hpc_init;
- retval = pciehprm_init(PCI);
- if (!retval) {
- retval = pcie_port_service_register(&hpdriver_portdrv);
- dbg("pcie_port_service_register = %d\n", retval);
- info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
- if (retval)
- dbg("%s: Failure to register service\n", __FUNCTION__);
- }
+ retval = pcie_port_service_register(&hpdriver_portdrv);
+ dbg("pcie_port_service_register = %d\n", retval);
+ info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+ if (retval)
+ dbg("%s: Failure to register service\n", __FUNCTION__);
error_hpc_init:
if (retval) {
- pciehprm_cleanup();
pciehp_event_stop_thread();
- } else
- pciehprm_print_pirt();
+ };
return retval;
}
@@ -663,9 +580,6 @@ static void __exit pcied_cleanup(void)
dbg("unload_pciehpd()\n");
unload_pciehpd();
- pciehprm_cleanup();
-
- dbg("pcie_port_service_unregister\n");
pcie_port_service_unregister(&hpdriver_portdrv);
info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 898f6da..5e582ec 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -27,25 +27,14 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
#include <linux/smp_lock.h>
#include <linux/pci.h>
#include "../pci.h"
#include "pciehp.h"
-#include "pciehprm.h"
-static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,
- u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
-static int configure_new_function( struct controller *ctrl, struct pci_func *func,
- u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
static void interrupt_event_handler(struct controller *ctrl);
static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
@@ -60,22 +49,18 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
struct slot *p_slot;
u8 rc = 0;
u8 getstatus;
- struct pci_func *func;
struct event_info *taskInfo;
/* Attention Button Change */
dbg("pciehp: Attention button interrupt received.\n");
- func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* This is the structure that tells the worker thread what to do */
taskInfo = &(ctrl->event_queue[ctrl->next_event]);
p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
- ctrl->next_event = (ctrl->next_event + 1) % 10;
+ ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
taskInfo->hp_slot = hp_slot;
rc++;
@@ -117,24 +102,20 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
struct slot *p_slot;
u8 rc = 0;
u8 getstatus;
- struct pci_func *func;
struct event_info *taskInfo;
/* Switch Change */
dbg("pciehp: Switch interrupt received.\n");
- func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* This is the structure that tells the worker thread
* what to do
*/
taskInfo = &(ctrl->event_queue[ctrl->next_event]);
- ctrl->next_event = (ctrl->next_event + 1) % 10;
+ ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
taskInfo->hp_slot = hp_slot;
rc++;
p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (getstatus) {
@@ -142,14 +123,12 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
* Switch opened
*/
info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
- func->switch_save = 0;
taskInfo->event_type = INT_SWITCH_OPEN;
} else {
/*
* Switch closed
*/
info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
- func->switch_save = 0x10;
taskInfo->event_type = INT_SWITCH_CLOSE;
}
@@ -163,20 +142,17 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
{
struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
- u8 rc = 0;
- struct pci_func *func;
+ u8 presence_save, rc = 0;
struct event_info *taskInfo;
/* Presence Change */
dbg("pciehp: Presence/Notify input change.\n");
- func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* This is the structure that tells the worker thread
* what to do
*/
taskInfo = &(ctrl->event_queue[ctrl->next_event]);
- ctrl->next_event = (ctrl->next_event + 1) % 10;
+ ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
taskInfo->hp_slot = hp_slot;
rc++;
@@ -185,8 +161,8 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
/* Switch is open, assume a presence change
* Save the presence state
*/
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
- if (func->presence_save) {
+ p_slot->hpc_ops->get_adapter_status(p_slot, &presence_save);
+ if (presence_save) {
/*
* Card Present
*/
@@ -211,19 +187,16 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u8 rc = 0;
- struct pci_func *func;
struct event_info *taskInfo;
/* power fault */
dbg("pciehp: Power fault interrupt received.\n");
- func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* this is the structure that tells the worker thread
* what to do
*/
taskInfo = &(ctrl->event_queue[ctrl->next_event]);
- ctrl->next_event = (ctrl->next_event + 1) % 10;
+ ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
taskInfo->hp_slot = hp_slot;
rc++;
@@ -234,7 +207,7 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
* power fault Cleared
*/
info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
- func->status = 0x00;
+ p_slot->status = 0x00;
taskInfo->event_type = INT_POWER_FAULT_CLEAR;
} else {
/*
@@ -243,7 +216,7 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
taskInfo->event_type = INT_POWER_FAULT;
/* set power fault status for this board */
- func->status = 0xFF;
+ p_slot->status = 0xFF;
info("power fault bit %x set\n", hp_slot);
}
if (rc)
@@ -252,810 +225,6 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
return rc;
}
-
-/**
- * sort_by_size: sort nodes by their length, smallest first.
- *
- * @head: list to sort
- */
-static int sort_by_size(struct pci_resource **head)
-{
- struct pci_resource *current_res;
- struct pci_resource *next_res;
- int out_of_order = 1;
-
- if (!(*head))
- return 1;
-
- if (!((*head)->next))
- return 0;
-
- while (out_of_order) {
- out_of_order = 0;
-
- /* Special case for swapping list head */
- if (((*head)->next) &&
- ((*head)->length > (*head)->next->length)) {
- out_of_order++;
- current_res = *head;
- *head = (*head)->next;
- current_res->next = (*head)->next;
- (*head)->next = current_res;
- }
-
- current_res = *head;
-
- while (current_res->next && current_res->next->next) {
- if (current_res->next->length > current_res->next->next->length) {
- out_of_order++;
- next_res = current_res->next;
- current_res->next = current_res->next->next;
- current_res = current_res->next;
- next_res->next = current_res->next;
- current_res->next = next_res;
- } else
- current_res = current_res->next;
- }
- } /* End of out_of_order loop */
-
- return 0;
-}
-
-
-/*
- * sort_by_max_size
- *
- * Sorts nodes on the list by their length.
- * Largest first.
- *
- */
-static int sort_by_max_size(struct pci_resource **head)
-{
- struct pci_resource *current_res;
- struct pci_resource *next_res;
- int out_of_order = 1;
-
- if (!(*head))
- return 1;
-
- if (!((*head)->next))
- return 0;
-
- while (out_of_order) {
- out_of_order = 0;
-
- /* Special case for swapping list head */
- if (((*head)->next) &&
- ((*head)->length < (*head)->next->length)) {
- out_of_order++;
- current_res = *head;
- *head = (*head)->next;
- current_res->next = (*head)->next;
- (*head)->next = current_res;
- }
-
- current_res = *head;
-
- while (current_res->next && current_res->next->next) {
- if (current_res->next->length < current_res->next->next->length) {
- out_of_order++;
- next_res = current_res->next;
- current_res->next = current_res->next->next;
- current_res = current_res->next;
- next_res->next = current_res->next;
- current_res->next = next_res;
- } else
- current_res = current_res->next;
- }
- } /* End of out_of_order loop */
-
- return 0;
-}
-
-
-/**
- * do_pre_bridge_resource_split: return one unused resource node
- * @head: list to scan
- *
- */
-static struct pci_resource *
-do_pre_bridge_resource_split(struct pci_resource **head,
- struct pci_resource **orig_head, u32 alignment)
-{
- struct pci_resource *prevnode = NULL;
- struct pci_resource *node;
- struct pci_resource *split_node;
- u32 rc;
- u32 temp_dword;
- dbg("do_pre_bridge_resource_split\n");
-
- if (!(*head) || !(*orig_head))
- return NULL;
-
- rc = pciehp_resource_sort_and_combine(head);
-
- if (rc)
- return NULL;
-
- if ((*head)->base != (*orig_head)->base)
- return NULL;
-
- if ((*head)->length == (*orig_head)->length)
- return NULL;
-
-
- /* If we got here, there the bridge requires some of the resource, but
- * we may be able to split some off of the front
- */
- node = *head;
-
- if (node->length & (alignment -1)) {
- /* this one isn't an aligned length, so we'll make a new entry
- * and split it up.
- */
- split_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- temp_dword = (node->length | (alignment-1)) + 1 - alignment;
-
- split_node->base = node->base;
- split_node->length = temp_dword;
-
- node->length -= temp_dword;
- node->base += split_node->length;
-
- /* Put it in the list */
- *head = split_node;
- split_node->next = node;
- }
-
- if (node->length < alignment)
- return NULL;
-
- /* Now unlink it */
- if (*head == node) {
- *head = node->next;
- } else {
- prevnode = *head;
- while (prevnode->next != node)
- prevnode = prevnode->next;
-
- prevnode->next = node->next;
- }
- node->next = NULL;
-
- return node;
-}
-
-
-/**
- * do_bridge_resource_split: return one unused resource node
- * @head: list to scan
- *
- */
-static struct pci_resource *
-do_bridge_resource_split(struct pci_resource **head, u32 alignment)
-{
- struct pci_resource *prevnode = NULL;
- struct pci_resource *node;
- u32 rc;
- u32 temp_dword;
-
- if (!(*head))
- return NULL;
-
- rc = pciehp_resource_sort_and_combine(head);
-
- if (rc)
- return NULL;
-
- node = *head;
-
- while (node->next) {
- prevnode = node;
- node = node->next;
- kfree(prevnode);
- }
-
- if (node->length < alignment) {
- kfree(node);
- return NULL;
- }
-
- if (node->base & (alignment - 1)) {
- /* Short circuit if adjusted size is too small */
- temp_dword = (node->base | (alignment-1)) + 1;
- if ((node->length - (temp_dword - node->base)) < alignment) {
- kfree(node);
- return NULL;
- }
-
- node->length -= (temp_dword - node->base);
- node->base = temp_dword;
- }
-
- if (node->length & (alignment - 1)) {
- /* There's stuff in use after this node */
- kfree(node);
- return NULL;
- }
-
- return node;
-}
-
-
-/*
- * get_io_resource
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length that is not in the
- * ISA aliasing window. If it finds a node larger than "size"
- * it will split it up.
- *
- * size must be a power of two.
- */
-static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size)
-{
- struct pci_resource *prevnode;
- struct pci_resource *node;
- struct pci_resource *split_node = NULL;
- u32 temp_dword;
-
- if (!(*head))
- return NULL;
-
- if ( pciehp_resource_sort_and_combine(head) )
- return NULL;
-
- if ( sort_by_size(head) )
- return NULL;
-
- for (node = *head; node; node = node->next) {
- if (node->length < size)
- continue;
-
- if (node->base & (size - 1)) {
- /* this one isn't base aligned properly
- so we'll make a new entry and split it up */
- temp_dword = (node->base | (size-1)) + 1;
-
- /*/ Short circuit if adjusted size is too small */
- if ((node->length - (temp_dword - node->base)) < size)
- continue;
-
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- split_node->base = node->base;
- split_node->length = temp_dword - node->base;
- node->base = temp_dword;
- node->length -= split_node->length;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of non-aligned base */
-
- /* Don't need to check if too small since we already did */
- if (node->length > size) {
- /* this one is longer than we need
- so we'll make a new entry and split it up */
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- split_node->base = node->base + size;
- split_node->length = node->length - size;
- node->length = size;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of too big on top end */
-
- /* For IO make sure it's not in the ISA aliasing space */
- if (node->base & 0x300L)
- continue;
-
- /* If we got here, then it is the right size
- Now take it out of the list */
- if (*head == node) {
- *head = node->next;
- } else {
- prevnode = *head;
- while (prevnode->next != node)
- prevnode = prevnode->next;
-
- prevnode->next = node->next;
- }
- node->next = NULL;
- /* Stop looping */
- break;
- }
-
- return node;
-}
-
-
-/*
- * get_max_resource
- *
- * Gets the largest node that is at least "size" big from the
- * list pointed to by head. It aligns the node on top and bottom
- * to "size" alignment before returning it.
- * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
- * This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
- */
-static struct pci_resource *get_max_resource(struct pci_resource **head, u32 size)
-{
- struct pci_resource *max;
- struct pci_resource *temp;
- struct pci_resource *split_node;
- u32 temp_dword;
- u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 };
- int i;
-
- if (!(*head))
- return NULL;
-
- if (pciehp_resource_sort_and_combine(head))
- return NULL;
-
- if (sort_by_max_size(head))
- return NULL;
-
- for (max = *head;max; max = max->next) {
-
- /* If not big enough we could probably just bail,
- instead we'll continue to the next. */
- if (max->length < size)
- continue;
-
- if (max->base & (size - 1)) {
- /* this one isn't base aligned properly
- so we'll make a new entry and split it up */
- temp_dword = (max->base | (size-1)) + 1;
-
- /* Short circuit if adjusted size is too small */
- if ((max->length - (temp_dword - max->base)) < size)
- continue;
-
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- split_node->base = max->base;
- split_node->length = temp_dword - max->base;
- max->base = temp_dword;
- max->length -= split_node->length;
-
- /* Put it next in the list */
- split_node->next = max->next;
- max->next = split_node;
- }
-
- if ((max->base + max->length) & (size - 1)) {
- /* this one isn't end aligned properly at the top
- so we'll make a new entry and split it up */
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
- temp_dword = ((max->base + max->length) & ~(size - 1));
- split_node->base = temp_dword;
- split_node->length = max->length + max->base
- - split_node->base;
- max->length -= split_node->length;
-
- /* Put it in the list */
- split_node->next = max->next;
- max->next = split_node;
- }
-
- /* Make sure it didn't shrink too much when we aligned it */
- if (max->length < size)
- continue;
-
- for ( i = 0; max_size[i] > size; i++) {
- if (max->length > max_size[i]) {
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!split_node)
- break; /* return NULL; */
- split_node->base = max->base + max_size[i];
- split_node->length = max->length - max_size[i];
- max->length = max_size[i];
- /* Put it next in the list */
- split_node->next = max->next;
- max->next = split_node;
- break;
- }
- }
-
- /* Now take it out of the list */
- temp = (struct pci_resource*) *head;
- if (temp == max) {
- *head = max->next;
- } else {
- while (temp && temp->next != max) {
- temp = temp->next;
- }
-
- temp->next = max->next;
- }
-
- max->next = NULL;
- return max;
- }
-
- /* If we get here, we couldn't find one */
- return NULL;
-}
-
-
-/*
- * get_resource
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length. If it finds a node
- * larger than "size" it will split it up.
- *
- * size must be a power of two.
- */
-static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
-{
- struct pci_resource *prevnode;
- struct pci_resource *node;
- struct pci_resource *split_node;
- u32 temp_dword;
-
- if (!(*head))
- return NULL;
-
- if ( pciehp_resource_sort_and_combine(head) )
- return NULL;
-
- if ( sort_by_size(head) )
- return NULL;
-
- for (node = *head; node; node = node->next) {
- dbg("%s: req_size =0x%x node=%p, base=0x%x, length=0x%x\n",
- __FUNCTION__, size, node, node->base, node->length);
- if (node->length < size)
- continue;
-
- if (node->base & (size - 1)) {
- dbg("%s: not aligned\n", __FUNCTION__);
- /* this one isn't base aligned properly
- so we'll make a new entry and split it up */
- temp_dword = (node->base | (size-1)) + 1;
-
- /* Short circuit if adjusted size is too small */
- if ((node->length - (temp_dword - node->base)) < size)
- continue;
-
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- split_node->base = node->base;
- split_node->length = temp_dword - node->base;
- node->base = temp_dword;
- node->length -= split_node->length;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of non-aligned base */
-
- /* Don't need to check if too small since we already did */
- if (node->length > size) {
- dbg("%s: too big\n", __FUNCTION__);
- /* this one is longer than we need
- so we'll make a new entry and split it up */
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- split_node->base = node->base + size;
- split_node->length = node->length - size;
- node->length = size;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of too big on top end */
-
- dbg("%s: got one!!!\n", __FUNCTION__);
- /* If we got here, then it is the right size
- Now take it out of the list */
- if (*head == node) {
- *head = node->next;
- } else {
- prevnode = *head;
- while (prevnode->next != node)
- prevnode = prevnode->next;
-
- prevnode->next = node->next;
- }
- node->next = NULL;
- /* Stop looping */
- break;
- }
- return node;
-}
-
-
-/*
- * pciehp_resource_sort_and_combine
- *
- * Sorts all of the nodes in the list in ascending order by
- * their base addresses. Also does garbage collection by
- * combining adjacent nodes.
- *
- * returns 0 if success
- */
-int pciehp_resource_sort_and_combine(struct pci_resource **head)
-{
- struct pci_resource *node1;
- struct pci_resource *node2;
- int out_of_order = 1;
-
- dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
-
- if (!(*head))
- return 1;
-
- dbg("*head->next = %p\n",(*head)->next);
-
- if (!(*head)->next)
- return 0; /* only one item on the list, already sorted! */
-
- dbg("*head->base = 0x%x\n",(*head)->base);
- dbg("*head->next->base = 0x%x\n",(*head)->next->base);
- while (out_of_order) {
- out_of_order = 0;
-
- /* Special case for swapping list head */
- if (((*head)->next) &&
- ((*head)->base > (*head)->next->base)) {
- node1 = *head;
- (*head) = (*head)->next;
- node1->next = (*head)->next;
- (*head)->next = node1;
- out_of_order++;
- }
-
- node1 = (*head);
-
- while (node1->next && node1->next->next) {
- if (node1->next->base > node1->next->next->base) {
- out_of_order++;
- node2 = node1->next;
- node1->next = node1->next->next;
- node1 = node1->next;
- node2->next = node1->next;
- node1->next = node2;
- } else
- node1 = node1->next;
- }
- } /* End of out_of_order loop */
-
- node1 = *head;
-
- while (node1 && node1->next) {
- if ((node1->base + node1->length) == node1->next->base) {
- /* Combine */
- dbg("8..\n");
- node1->length += node1->next->length;
- node2 = node1->next;
- node1->next = node1->next->next;
- kfree(node2);
- } else
- node1 = node1->next;
- }
-
- return 0;
-}
-
-
-/**
- * pciehp_slot_create - Creates a node and adds it to the proper bus.
- * @busnumber - bus where new node is to be located
- *
- * Returns pointer to the new node or NULL if unsuccessful
- */
-struct pci_func *pciehp_slot_create(u8 busnumber)
-{
- struct pci_func *new_slot;
- struct pci_func *next;
- dbg("%s: busnumber %x\n", __FUNCTION__, busnumber);
- new_slot = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
-
- if (new_slot == NULL)
- return new_slot;
-
- memset(new_slot, 0, sizeof(struct pci_func));
-
- new_slot->next = NULL;
- new_slot->configured = 1;
-
- if (pciehp_slot_list[busnumber] == NULL) {
- pciehp_slot_list[busnumber] = new_slot;
- } else {
- next = pciehp_slot_list[busnumber];
- while (next->next != NULL)
- next = next->next;
- next->next = new_slot;
- }
- return new_slot;
-}
-
-
-/**
- * slot_remove - Removes a node from the linked list of slots.
- * @old_slot: slot to remove
- *
- * Returns 0 if successful, !0 otherwise.
- */
-static int slot_remove(struct pci_func * old_slot)
-{
- struct pci_func *next;
-
- if (old_slot == NULL)
- return 1;
-
- next = pciehp_slot_list[old_slot->bus];
-
- if (next == NULL)
- return 1;
-
- if (next == old_slot) {
- pciehp_slot_list[old_slot->bus] = old_slot->next;
- pciehp_destroy_board_resources(old_slot);
- kfree(old_slot);
- return 0;
- }
-
- while ((next->next != old_slot) && (next->next != NULL)) {
- next = next->next;
- }
-
- if (next->next == old_slot) {
- next->next = old_slot->next;
- pciehp_destroy_board_resources(old_slot);
- kfree(old_slot);
- return 0;
- } else
- return 2;
-}
-
-
-/**
- * bridge_slot_remove - Removes a node from the linked list of slots.
- * @bridge: bridge to remove
- *
- * Returns 0 if successful, !0 otherwise.
- */
-static int bridge_slot_remove(struct pci_func *bridge)
-{
- u8 subordinateBus, secondaryBus;
- u8 tempBus;
- struct pci_func *next;
-
- if (bridge == NULL)
- return 1;
-
- secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
- subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
-
- for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
- next = pciehp_slot_list[tempBus];
-
- while (!slot_remove(next)) {
- next = pciehp_slot_list[tempBus];
- }
- }
-
- next = pciehp_slot_list[bridge->bus];
-
- if (next == NULL) {
- return 1;
- }
-
- if (next == bridge) {
- pciehp_slot_list[bridge->bus] = bridge->next;
- kfree(bridge);
- return 0;
- }
-
- while ((next->next != bridge) && (next->next != NULL)) {
- next = next->next;
- }
-
- if (next->next == bridge) {
- next->next = bridge->next;
- kfree(bridge);
- return 0;
- } else
- return 2;
-}
-
-
-/**
- * pciehp_slot_find - Looks for a node by bus, and device, multiple functions accessed
- * @bus: bus to find
- * @device: device to find
- * @index: is 0 for first function found, 1 for the second...
- *
- * Returns pointer to the node if successful, %NULL otherwise.
- */
-struct pci_func *pciehp_slot_find(u8 bus, u8 device, u8 index)
-{
- int found = -1;
- struct pci_func *func;
-
- func = pciehp_slot_list[bus];
- dbg("%s: bus %x device %x index %x\n",
- __FUNCTION__, bus, device, index);
- if (func != NULL) {
- dbg("%s: func-> bus %x device %x function %x pci_dev %p\n",
- __FUNCTION__, func->bus, func->device, func->function,
- func->pci_dev);
- } else
- dbg("%s: func == NULL\n", __FUNCTION__);
-
- if ((func == NULL) || ((func->device == device) && (index == 0)))
- return func;
-
- if (func->device == device)
- found++;
-
- while (func->next != NULL) {
- func = func->next;
-
- dbg("%s: In while loop, func-> bus %x device %x function %x pci_dev %p\n",
- __FUNCTION__, func->bus, func->device, func->function,
- func->pci_dev);
- if (func->device == device)
- found++;
- dbg("%s: while loop, found %d, index %d\n", __FUNCTION__,
- found, index);
-
- if ((found == index) || (func->function == index)) {
- dbg("%s: Found bus %x dev %x func %x\n", __FUNCTION__,
- func->bus, func->device, func->function);
- return func;
- }
- }
-
- return NULL;
-}
-
-static int is_bridge(struct pci_func * func)
-{
- /* Check the header type */
- if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
- return 1;
- else
- return 0;
-}
-
-
/* The following routines constitute the bulk of the
hotplug controller logic
*/
@@ -1100,20 +269,17 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
* Configures board
*
*/
-static u32 board_added(struct pci_func * func, struct controller * ctrl)
+static int board_added(struct slot *p_slot)
{
u8 hp_slot;
- int index;
- u32 temp_register = 0xFFFFFFFF;
- u32 rc = 0;
- struct pci_func *new_func = NULL;
- struct slot *p_slot;
- struct resource_lists res_lists;
+ int rc = 0;
+ struct controller *ctrl = p_slot->ctrl;
- p_slot = pciehp_find_slot(ctrl, func->device);
- hp_slot = func->device - ctrl->slot_device_offset;
+ hp_slot = p_slot->device - ctrl->slot_device_offset;
- dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
+ dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
+ __FUNCTION__, p_slot->device,
+ ctrl->slot_device_offset, hp_slot);
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
@@ -1141,9 +307,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
up(&ctrl->crit_sect);
/* Wait for ~1 second */
- dbg("%s: before long_delay\n", __FUNCTION__);
wait_for_ctrl_irq (ctrl);
- dbg("%s: afterlong_delay\n", __FUNCTION__);
/* Check link training status */
rc = p_slot->hpc_ops->check_lnk_status(ctrl);
@@ -1153,98 +317,47 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
return rc;
}
- dbg("%s: func status = %x\n", __FUNCTION__, func->status);
+ dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status);
/* Check for a power fault */
- if (func->status == 0xFF) {
+ if (p_slot->status == 0xFF) {
/* power fault occurred, but it was benign */
- temp_register = 0xFFFFFFFF;
- dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
rc = POWER_FAILURE;
- func->status = 0;
- } else {
- /* Get vendor/device ID u32 */
- rc = pci_bus_read_config_dword (ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function),
- PCI_VENDOR_ID, &temp_register);
- dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc);
- dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
-
- if (rc != 0) {
- /* Something's wrong here */
- temp_register = 0xFFFFFFFF;
- dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
- }
- /* Preset return code. It will be changed later if things go okay. */
- rc = NO_ADAPTER_PRESENT;
+ p_slot->status = 0;
+ goto err_exit;
}
- /* All F's is an empty slot or an invalid board */
- if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */
- res_lists.io_head = ctrl->io_head;
- res_lists.mem_head = ctrl->mem_head;
- res_lists.p_mem_head = ctrl->p_mem_head;
- res_lists.bus_head = ctrl->bus_head;
- res_lists.irqs = NULL;
-
- rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0);
- dbg("%s: back from configure_new_device\n", __FUNCTION__);
-
- ctrl->io_head = res_lists.io_head;
- ctrl->mem_head = res_lists.mem_head;
- ctrl->p_mem_head = res_lists.p_mem_head;
- ctrl->bus_head = res_lists.bus_head;
+ rc = pciehp_configure_device(p_slot);
+ if (rc) {
+ err("Cannot add device 0x%x:%x\n", p_slot->bus,
+ p_slot->device);
+ goto err_exit;
+ }
- pciehp_resource_sort_and_combine(&(ctrl->mem_head));
- pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
- pciehp_resource_sort_and_combine(&(ctrl->io_head));
- pciehp_resource_sort_and_combine(&(ctrl->bus_head));
+ p_slot->status = 0;
- if (rc) {
- set_slot_off(ctrl, p_slot);
- return rc;
- }
- pciehp_save_slot_config(ctrl, func);
-
- func->status = 0;
- func->switch_save = 0x10;
- func->is_a_board = 0x01;
+ /*
+ * Some PCI Express root ports require fixup after hot-plug operation.
+ */
+ if (pcie_mch_quirk)
+ pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
+ if (PWR_LED(ctrl->ctrlcap)) {
+ /* Wait for exclusive access to hardware */
+ down(&ctrl->crit_sect);
- /* next, we will instantiate the linux pci_dev structures
- * (with appropriate driver notification, if already present)
- */
- index = 0;
- do {
- new_func = pciehp_slot_find(ctrl->slot_bus, func->device, index++);
- if (new_func && !new_func->pci_dev) {
- dbg("%s:call pci_hp_configure_dev, func %x\n",
- __FUNCTION__, index);
- pciehp_configure_device(ctrl, new_func);
- }
- } while (new_func);
-
- /*
- * Some PCI Express root ports require fixup after hot-plug operation.
- */
- if (pcie_mch_quirk)
- pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
-
- if (PWR_LED(ctrl->ctrlcap)) {
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- p_slot->hpc_ops->green_led_on(p_slot);
+ p_slot->hpc_ops->green_led_on(p_slot);
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- }
- } else {
- set_slot_off(ctrl, p_slot);
- return -1;
- }
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
+ }
return 0;
+
+err_exit:
+ set_slot_off(ctrl, p_slot);
+ return -1;
}
@@ -1252,55 +365,25 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
* remove_board - Turns off slot and LED's
*
*/
-static u32 remove_board(struct pci_func *func, struct controller *ctrl)
+static int remove_board(struct slot *p_slot)
{
- int index;
- u8 skip = 0;
u8 device;
u8 hp_slot;
- u32 rc;
- struct resource_lists res_lists;
- struct pci_func *temp_func;
- struct slot *p_slot;
-
- if (func == NULL)
- return 1;
+ int rc;
+ struct controller *ctrl = p_slot->ctrl;
- if (pciehp_unconfigure_device(func))
+ if (pciehp_unconfigure_device(p_slot))
return 1;
- device = func->device;
+ device = p_slot->device;
- hp_slot = func->device - ctrl->slot_device_offset;
+ hp_slot = p_slot->device - ctrl->slot_device_offset;
p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
- if ((ctrl->add_support) &&
- !(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) {
- /* Here we check to see if we've saved any of the board's
- * resources already. If so, we'll skip the attempt to
- * determine what's being used.
- */
- index = 0;
-
- temp_func = func;
-
- while ((temp_func = pciehp_slot_find(temp_func->bus, temp_func->device, index++))) {
- if (temp_func->bus_head || temp_func->mem_head
- || temp_func->p_mem_head || temp_func->io_head) {
- skip = 1;
- break;
- }
- }
-
- if (!skip)
- rc = pciehp_save_used_resources(ctrl, func, DISABLE_CARD);
- }
/* Change status to shutdown */
- if (func->is_a_board)
- func->status = 0x01;
- func->configured = 0;
+ p_slot->status = 0x01;
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
@@ -1328,56 +411,6 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl)
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
- if (ctrl->add_support) {
- while (func) {
- res_lists.io_head = ctrl->io_head;
- res_lists.mem_head = ctrl->mem_head;
- res_lists.p_mem_head = ctrl->p_mem_head;
- res_lists.bus_head = ctrl->bus_head;
-
- dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n",
- func->bus, func->device, func->function);
-
- pciehp_return_board_resources(func, &res_lists);
-
- ctrl->io_head = res_lists.io_head;
- ctrl->mem_head = res_lists.mem_head;
- ctrl->p_mem_head = res_lists.p_mem_head;
- ctrl->bus_head = res_lists.bus_head;
-
- pciehp_resource_sort_and_combine(&(ctrl->mem_head));
- pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
- pciehp_resource_sort_and_combine(&(ctrl->io_head));
- pciehp_resource_sort_and_combine(&(ctrl->bus_head));
-
- if (is_bridge(func)) {
- dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
- ctrl->seg, func->bus, func->device, func->function);
- bridge_slot_remove(func);
- } else {
- dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
- ctrl->seg, func->bus, func->device, func->function);
- slot_remove(func);
- }
-
- func = pciehp_slot_find(ctrl->slot_bus, device, 0);
- }
-
- /* Setup slot structure with entry for empty slot */
- func = pciehp_slot_create(ctrl->slot_bus);
-
- if (func == NULL) {
- return 1;
- }
-
- func->bus = ctrl->slot_bus;
- func->device = device;
- func->function = 0;
- func->configured = 0;
- func->switch_save = 0x10;
- func->is_a_board = 0;
- }
-
return 0;
}
@@ -1411,13 +444,15 @@ static void pciehp_pushbutton_thread(unsigned long slot)
p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (getstatus) {
p_slot->state = POWEROFF_STATE;
- dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+ dbg("%s: disabling bus:device(%x:%x)\n", __FUNCTION__,
+ p_slot->bus, p_slot->device);
pciehp_disable_slot(p_slot);
p_slot->state = STATIC_STATE;
} else {
p_slot->state = POWERON_STATE;
- dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+ dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__,
+ p_slot->bus, p_slot->device);
if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
/* Wait for exclusive access to hardware */
@@ -1459,13 +494,15 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (!getstatus) {
p_slot->state = POWEROFF_STATE;
- dbg("In removing board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+ dbg("%s: removing bus:device(%x:%x)\n",
+ __FUNCTION__, p_slot->bus, p_slot->device);
pciehp_disable_slot(p_slot);
p_slot->state = STATIC_STATE;
} else {
p_slot->state = POWERON_STATE;
- dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+ dbg("%s: adding bus:device(%x:%x)\n",
+ __FUNCTION__, p_slot->bus, p_slot->device);
if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
/* Wait for exclusive access to hardware */
@@ -1531,7 +568,6 @@ int pciehp_event_start_thread(void)
err ("Can't start up our event thread\n");
return -1;
}
- dbg("Our event thread pid = %d\n", pid);
return 0;
}
@@ -1539,9 +575,7 @@ int pciehp_event_start_thread(void)
void pciehp_event_stop_thread(void)
{
event_finished = 1;
- dbg("event_thread finish command given\n");
up(&event_semaphore);
- dbg("wait for event_thread to exit\n");
down(&event_exit);
}
@@ -1573,7 +607,6 @@ static void interrupt_event_handler(struct controller *ctrl)
{
int loop = 0;
int change = 1;
- struct pci_func *func;
u8 hp_slot;
u8 getstatus;
struct slot *p_slot;
@@ -1581,16 +614,12 @@ static void interrupt_event_handler(struct controller *ctrl)
while (change) {
change = 0;
- for (loop = 0; loop < 10; loop++) {
+ for (loop = 0; loop < MAX_EVENTS; loop++) {
if (ctrl->event_queue[loop].event_type != 0) {
hp_slot = ctrl->event_queue[loop].hp_slot;
- func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
- dbg("hp_slot %d, func %p, p_slot %p\n", hp_slot, func, p_slot);
-
if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) {
dbg("button cancel\n");
del_timer(&p_slot->task_event);
@@ -1682,7 +711,6 @@ static void interrupt_event_handler(struct controller *ctrl)
p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
p_slot->task_event.data = (unsigned long) p_slot;
- dbg("add_timer p_slot = %p\n", (void *) p_slot);
add_timer(&p_slot->task_event);
}
}
@@ -1737,13 +765,6 @@ int pciehp_enable_slot(struct slot *p_slot)
{
u8 getstatus = 0;
int rc;
- struct pci_func *func;
-
- func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
- if (!func) {
- dbg("%s: Error! slot NULL\n", __FUNCTION__);
- return 1;
- }
/* Check to see if (latch closed, card present, power off) */
down(&p_slot->ctrl->crit_sect);
@@ -1773,45 +794,11 @@ int pciehp_enable_slot(struct slot *p_slot)
}
up(&p_slot->ctrl->crit_sect);
- slot_remove(func);
-
- func = pciehp_slot_create(p_slot->bus);
- if (func == NULL)
- return 1;
-
- func->bus = p_slot->bus;
- func->device = p_slot->device;
- func->function = 0;
- func->configured = 0;
- func->is_a_board = 1;
-
- /* We have to save the presence info for these slots */
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
- func->switch_save = !getstatus? 0x10:0;
- rc = board_added(func, p_slot->ctrl);
+ rc = board_added(p_slot);
if (rc) {
- if (is_bridge(func))
- bridge_slot_remove(func);
- else
- slot_remove(func);
-
- /* Setup slot structure with entry for empty slot */
- func = pciehp_slot_create(p_slot->bus);
- if (func == NULL)
- return 1; /* Out of memory */
-
- func->bus = p_slot->bus;
- func->device = p_slot->device;
- func->function = 0;
- func->configured = 0;
- func->is_a_board = 1;
-
- /* We have to save the presence info for these slots */
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
- func->switch_save = !getstatus? 0x10:0;
}
if (p_slot)
@@ -1823,14 +810,8 @@ int pciehp_enable_slot(struct slot *p_slot)
int pciehp_disable_slot(struct slot *p_slot)
{
- u8 class_code, header_type, BCR;
- u8 index = 0;
u8 getstatus = 0;
- u32 rc = 0;
int ret = 0;
- unsigned int devfn;
- struct pci_bus *pci_bus = p_slot->ctrl->pci_dev->subordinate;
- struct pci_func *func;
if (!p_slot->ctrl)
return 1;
@@ -1867,838 +848,8 @@ int pciehp_disable_slot(struct slot *p_slot)
up(&p_slot->ctrl->crit_sect);
- func = pciehp_slot_find(p_slot->bus, p_slot->device, index++);
-
- /* Make sure there are no video controllers here
- * for all func of p_slot
- */
- while (func && !rc) {
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- /* Check the Class Code */
- rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
- if (rc)
- return rc;
-
- if (class_code == PCI_BASE_CLASS_DISPLAY) {
- /* Display/Video adapter (not supported) */
- rc = REMOVE_NOT_SUPPORTED;
- } else {
- /* See if it's a bridge */
- rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
- if (rc)
- return rc;
-
- /* If it's a bridge, check the VGA Enable bit */
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
- rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
- if (rc)
- return rc;
-
- /* If the VGA Enable bit is set, remove isn't supported */
- if (BCR & PCI_BRIDGE_CTL_VGA) {
- rc = REMOVE_NOT_SUPPORTED;
- }
- }
- }
-
- func = pciehp_slot_find(p_slot->bus, p_slot->device, index++);
- }
-
- func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
- if ((func != NULL) && !rc) {
- rc = remove_board(func, p_slot->ctrl);
- } else if (!rc)
- rc = 1;
-
- if (p_slot)
- update_slot_info(p_slot);
-
- return rc;
-}
-
-
-/**
- * configure_new_device - Configures the PCI header information of one board.
- *
- * @ctrl: pointer to controller structure
- * @func: pointer to function structure
- * @behind_bridge: 1 if this is a recursive call, 0 if not
- * @resources: pointer to set of resource lists
- *
- * Returns 0 if success
- *
- */
-static u32 configure_new_device(struct controller * ctrl, struct pci_func * func,
- u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev)
-{
- u8 temp_byte, function, max_functions, stop_it;
- int rc;
- u32 ID;
- struct pci_func *new_slot;
- struct pci_bus lpci_bus, *pci_bus;
- int index;
-
- new_slot = func;
-
- dbg("%s\n", __FUNCTION__);
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
-
- /* Check for Multi-function device */
- rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
- if (rc) {
- dbg("%s: rc = %d\n", __FUNCTION__, rc);
- return rc;
- }
-
- if (temp_byte & 0x80) /* Multi-function device */
- max_functions = 8;
- else
- max_functions = 1;
-
- function = 0;
-
- do {
- rc = configure_new_function(ctrl, new_slot, behind_bridge,
- resources, bridge_bus, bridge_dev);
-
- if (rc) {
- dbg("configure_new_function failed: %d\n", rc);
- index = 0;
-
- while (new_slot) {
- new_slot = pciehp_slot_find(new_slot->bus,
- new_slot->device, index++);
-
- if (new_slot)
- pciehp_return_board_resources(new_slot,
- resources);
- }
-
- return rc;
- }
-
- function++;
-
- stop_it = 0;
-
- /* The following loop skips to the next present function
- * and creates a board structure
- */
-
- while ((function < max_functions) && (!stop_it)) {
- pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
-
- if (ID == 0xFFFFFFFF) { /* There's nothing there. */
- function++;
- } else { /* There's something there */
- /* Setup slot structure. */
- new_slot = pciehp_slot_create(func->bus);
-
- if (new_slot == NULL) {
- /* Out of memory */
- return 1;
- }
-
- new_slot->bus = func->bus;
- new_slot->device = func->device;
- new_slot->function = function;
- new_slot->is_a_board = 1;
- new_slot->status = 0;
-
- stop_it++;
- }
- }
-
- } while (function < max_functions);
- dbg("returning from %s\n", __FUNCTION__);
-
- return 0;
-}
-
-/*
- * Configuration logic that involves the hotplug data structures and
- * their bookkeeping
- */
-
-/**
- * configure_bridge: fill bridge's registers, either configure or disable it.
- */
-static int
-configure_bridge(struct pci_bus *pci_bus, unsigned int devfn,
- struct pci_resource *mem_node,
- struct pci_resource **hold_mem_node,
- int base_addr, int limit_addr)
-{
- u16 temp_word;
- u32 rc;
-
- if (mem_node) {
- memcpy(*hold_mem_node, mem_node, sizeof(struct pci_resource));
- mem_node->next = NULL;
-
- /* set Mem base and Limit registers */
- RES_CHECK(mem_node->base, 16);
- temp_word = (u16)(mem_node->base >> 16);
- rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
-
- RES_CHECK(mem_node->base + mem_node->length - 1, 16);
- temp_word = (u16)((mem_node->base + mem_node->length - 1) >> 16);
- rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
- } else {
- temp_word = 0xFFFF;
- rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
-
- temp_word = 0x0000;
- rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
-
- kfree(*hold_mem_node);
- *hold_mem_node = NULL;
- }
- return rc;
-}
-
-static int
-configure_new_bridge(struct controller *ctrl, struct pci_func *func,
- u8 behind_bridge, struct resource_lists *resources,
- struct pci_bus *pci_bus)
-{
- int cloop;
- u8 temp_byte;
- u8 device;
- u16 temp_word;
- u32 rc;
- u32 ID;
- unsigned int devfn;
- struct pci_resource *mem_node;
- struct pci_resource *p_mem_node;
- struct pci_resource *io_node;
- struct pci_resource *bus_node;
- struct pci_resource *hold_mem_node;
- struct pci_resource *hold_p_mem_node;
- struct pci_resource *hold_IO_node;
- struct pci_resource *hold_bus_node;
- struct irq_mapping irqs;
- struct pci_func *new_slot;
- struct resource_lists temp_resources;
-
- devfn = PCI_DEVFN(func->device, func->function);
-
- /* set Primary bus */
- dbg("set Primary bus = 0x%x\n", func->bus);
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
- if (rc)
- return rc;
-
- /* find range of busses to use */
- bus_node = get_max_resource(&resources->bus_head, 1L);
-
- /* If we don't have any busses to allocate, we can't continue */
- if (!bus_node) {
- err("Got NO bus resource to use\n");
- return -ENOMEM;
- }
- dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length);
-
- /* set Secondary bus */
- temp_byte = (u8)bus_node->base;
- dbg("set Secondary bus = 0x%x\n", temp_byte);
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
- if (rc)
- return rc;
-
- /* set subordinate bus */
- temp_byte = (u8)(bus_node->base + bus_node->length - 1);
- dbg("set subordinate bus = 0x%x\n", temp_byte);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
- if (rc)
- return rc;
-
- /* Set HP parameters (Cache Line Size, Latency Timer) */
- rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
- if (rc)
- return rc;
-
- /* Setup the IO, memory, and prefetchable windows */
-
- io_node = get_max_resource(&(resources->io_head), 0x1000L);
- if (io_node) {
- dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base,
- io_node->length, io_node->next);
- }
-
- mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
- if (mem_node) {
- dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base,
- mem_node->length, mem_node->next);
- }
-
- if (resources->p_mem_head)
- p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L);
- else {
- /*
- * In some platform implementation, MEM and PMEM are not
- * distinguished, and hence ACPI _CRS has only MEM entries
- * for both MEM and PMEM.
- */
- dbg("using MEM for PMEM\n");
- p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
- }
- if (p_mem_node) {
- dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base,
- p_mem_node->length, p_mem_node->next);
- }
-
- /* set up the IRQ info */
- if (!resources->irqs) {
- irqs.barber_pole = 0;
- irqs.interrupt[0] = 0;
- irqs.interrupt[1] = 0;
- irqs.interrupt[2] = 0;
- irqs.interrupt[3] = 0;
- irqs.valid_INT = 0;
- } else {
- irqs.barber_pole = resources->irqs->barber_pole;
- irqs.interrupt[0] = resources->irqs->interrupt[0];
- irqs.interrupt[1] = resources->irqs->interrupt[1];
- irqs.interrupt[2] = resources->irqs->interrupt[2];
- irqs.interrupt[3] = resources->irqs->interrupt[3];
- irqs.valid_INT = resources->irqs->valid_INT;
- }
-
- /* set up resource lists that are now aligned on top and bottom
- * for anything behind the bridge.
- */
- temp_resources.bus_head = bus_node;
- temp_resources.io_head = io_node;
- temp_resources.mem_head = mem_node;
- temp_resources.p_mem_head = p_mem_node;
- temp_resources.irqs = &irqs;
-
- /* Make copies of the nodes we are going to pass down so that
- * if there is a problem,we can just use these to free resources
- */
- hold_bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- hold_IO_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- hold_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- hold_p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
- if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
- kfree(hold_bus_node);
- kfree(hold_IO_node);
- kfree(hold_mem_node);
- kfree(hold_p_mem_node);
-
- return 1;
- }
-
- memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
-
- bus_node->base += 1;
- bus_node->length -= 1;
- bus_node->next = NULL;
-
- /* If we have IO resources copy them and fill in the bridge's
- * IO range registers
- */
- if (io_node) {
- memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
- io_node->next = NULL;
-
- /* set IO base and Limit registers */
- RES_CHECK(io_node->base, 8);
- temp_byte = (u8)(io_node->base >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
-
- RES_CHECK(io_node->base + io_node->length - 1, 8);
- temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
- } else {
- kfree(hold_IO_node);
- hold_IO_node = NULL;
- }
-
- /* If we have memory resources copy them and fill in the bridge's
- * memory range registers. Otherwise, fill in the range
- * registers with values that disable them.
- */
- rc = configure_bridge(pci_bus, devfn, mem_node, &hold_mem_node,
- PCI_MEMORY_BASE, PCI_MEMORY_LIMIT);
-
- /* If we have prefetchable memory resources copy them and
- * fill in the bridge's memory range registers. Otherwise,
- * fill in the range registers with values that disable them.
- */
- rc = configure_bridge(pci_bus, devfn, p_mem_node, &hold_p_mem_node,
- PCI_PREF_MEMORY_BASE, PCI_PREF_MEMORY_LIMIT);
-
- /* Adjust this to compensate for extra adjustment in first loop */
- irqs.barber_pole--;
-
- rc = 0;
-
- /* Here we actually find the devices and configure them */
- for (device = 0; (device <= 0x1F) && !rc; device++) {
- irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
-
- ID = 0xFFFFFFFF;
- pci_bus->number = hold_bus_node->base;
- pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
- pci_bus->number = func->bus;
-
- if (ID != 0xFFFFFFFF) { /* device Present */
- /* Setup slot structure. */
- new_slot = pciehp_slot_create(hold_bus_node->base);
-
- if (new_slot == NULL) {
- /* Out of memory */
- rc = -ENOMEM;
- continue;
- }
-
- new_slot->bus = hold_bus_node->base;
- new_slot->device = device;
- new_slot->function = 0;
- new_slot->is_a_board = 1;
- new_slot->status = 0;
-
- rc = configure_new_device(ctrl, new_slot, 1,
- &temp_resources, func->bus,
- func->device);
- dbg("configure_new_device rc=0x%x\n",rc);
- } /* End of IF (device in slot?) */
- } /* End of FOR loop */
-
- if (rc) {
- pciehp_destroy_resource_list(&temp_resources);
-
- return_resource(&(resources->bus_head), hold_bus_node);
- return_resource(&(resources->io_head), hold_IO_node);
- return_resource(&(resources->mem_head), hold_mem_node);
- return_resource(&(resources->p_mem_head), hold_p_mem_node);
- return(rc);
- }
-
- /* save the interrupt routing information */
- if (resources->irqs) {
- resources->irqs->interrupt[0] = irqs.interrupt[0];
- resources->irqs->interrupt[1] = irqs.interrupt[1];
- resources->irqs->interrupt[2] = irqs.interrupt[2];
- resources->irqs->interrupt[3] = irqs.interrupt[3];
- resources->irqs->valid_INT = irqs.valid_INT;
- } else if (!behind_bridge) {
- /* We need to hook up the interrupts here */
- for (cloop = 0; cloop < 4; cloop++) {
- if (irqs.valid_INT & (0x01 << cloop)) {
- rc = pciehp_set_irq(func->bus, func->device,
- 0x0A + cloop, irqs.interrupt[cloop]);
- if (rc) {
- pciehp_destroy_resource_list (&temp_resources);
- return_resource(&(resources->bus_head), hold_bus_node);
- return_resource(&(resources->io_head), hold_IO_node);
- return_resource(&(resources->mem_head), hold_mem_node);
- return_resource(&(resources->p_mem_head), hold_p_mem_node);
- return rc;
- }
- }
- } /* end of for loop */
- }
-
- /* Return unused bus resources
- * First use the temporary node to store information for the board
- */
- if (hold_bus_node && bus_node && temp_resources.bus_head) {
- hold_bus_node->length = bus_node->base - hold_bus_node->base;
-
- hold_bus_node->next = func->bus_head;
- func->bus_head = hold_bus_node;
-
- temp_byte = (u8)(temp_resources.bus_head->base - 1);
-
- /* set subordinate bus */
- dbg("re-set subordinate bus = 0x%x\n", temp_byte);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
-
- if (temp_resources.bus_head->length == 0) {
- kfree(temp_resources.bus_head);
- temp_resources.bus_head = NULL;
- } else {
- dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n",
- func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length);
- return_resource(&(resources->bus_head), temp_resources.bus_head);
- }
- }
-
- /* If we have IO space available and there is some left,
- * return the unused portion
- */
- if (hold_IO_node && temp_resources.io_head) {
- io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
- &hold_IO_node, 0x1000);
-
- /* Check if we were able to split something off */
- if (io_node) {
- hold_IO_node->base = io_node->base + io_node->length;
-
- RES_CHECK(hold_IO_node->base, 8);
- temp_byte = (u8)((hold_IO_node->base) >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
-
- return_resource(&(resources->io_head), io_node);
- }
-
- io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
-
- /* Check if we were able to split something off */
- if (io_node) {
- /* First use the temporary node to store information for the board */
- hold_IO_node->length = io_node->base - hold_IO_node->base;
-
- /* If we used any, add it to the board's list */
- if (hold_IO_node->length) {
- hold_IO_node->next = func->io_head;
- func->io_head = hold_IO_node;
-
- RES_CHECK(io_node->base - 1, 8);
- temp_byte = (u8)((io_node->base - 1) >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
-
- return_resource(&(resources->io_head), io_node);
- } else {
- /* it doesn't need any IO */
- temp_byte = 0x00;
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
-
- return_resource(&(resources->io_head), io_node);
- kfree(hold_IO_node);
- }
- } else {
- /* it used most of the range */
- hold_IO_node->next = func->io_head;
- func->io_head = hold_IO_node;
- }
- } else if (hold_IO_node) {
- /* it used the whole range */
- hold_IO_node->next = func->io_head;
- func->io_head = hold_IO_node;
- }
-
- /* If we have memory space available and there is some left,
- * return the unused portion
- */
- if (hold_mem_node && temp_resources.mem_head) {
- mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L);
-
- /* Check if we were able to split something off */
- if (mem_node) {
- hold_mem_node->base = mem_node->base + mem_node->length;
-
- RES_CHECK(hold_mem_node->base, 16);
- temp_word = (u16)((hold_mem_node->base) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
-
- return_resource(&(resources->mem_head), mem_node);
- }
-
- mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L);
-
- /* Check if we were able to split something off */
- if (mem_node) {
- /* First use the temporary node to store information for the board */
- hold_mem_node->length = mem_node->base - hold_mem_node->base;
-
- if (hold_mem_node->length) {
- hold_mem_node->next = func->mem_head;
- func->mem_head = hold_mem_node;
-
- /* configure end address */
- RES_CHECK(mem_node->base - 1, 16);
- temp_word = (u16)((mem_node->base - 1) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
-
- /* Return unused resources to the pool */
- return_resource(&(resources->mem_head), mem_node);
- } else {
- /* it doesn't need any Mem */
- temp_word = 0x0000;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
-
- return_resource(&(resources->mem_head), mem_node);
- kfree(hold_mem_node);
- }
- } else {
- /* it used most of the range */
- hold_mem_node->next = func->mem_head;
- func->mem_head = hold_mem_node;
- }
- } else if (hold_mem_node) {
- /* it used the whole range */
- hold_mem_node->next = func->mem_head;
- func->mem_head = hold_mem_node;
- }
-
- /* If we have prefetchable memory space available and there is some
- * left at the end, return the unused portion
- */
- if (hold_p_mem_node && temp_resources.p_mem_head) {
- p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
- &hold_p_mem_node, 0x100000L);
-
- /* Check if we were able to split something off */
- if (p_mem_node) {
- hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
-
- RES_CHECK(hold_p_mem_node->base, 16);
- temp_word = (u16)((hold_p_mem_node->base) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
-
- return_resource(&(resources->p_mem_head), p_mem_node);
- }
-
- p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L);
-
- /* Check if we were able to split something off */
- if (p_mem_node) {
- /* First use the temporary node to store information for the board */
- hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
-
- /* If we used any, add it to the board's list */
- if (hold_p_mem_node->length) {
- hold_p_mem_node->next = func->p_mem_head;
- func->p_mem_head = hold_p_mem_node;
-
- RES_CHECK(p_mem_node->base - 1, 16);
- temp_word = (u16)((p_mem_node->base - 1) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-
- return_resource(&(resources->p_mem_head), p_mem_node);
- } else {
- /* it doesn't need any PMem */
- temp_word = 0x0000;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-
- return_resource(&(resources->p_mem_head), p_mem_node);
- kfree(hold_p_mem_node);
- }
- } else {
- /* it used the most of the range */
- hold_p_mem_node->next = func->p_mem_head;
- func->p_mem_head = hold_p_mem_node;
- }
- } else if (hold_p_mem_node) {
- /* it used the whole range */
- hold_p_mem_node->next = func->p_mem_head;
- func->p_mem_head = hold_p_mem_node;
- }
-
- /* We should be configuring an IRQ and the bridge's base address
- * registers if it needs them. Although we have never seen such
- * a device
- */
-
- pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
-
- dbg("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
-
- return rc;
+ ret = remove_board(p_slot);
+ update_slot_info(p_slot);
+ return ret;
}
-/**
- * configure_new_function - Configures the PCI header information of one device
- *
- * @ctrl: pointer to controller structure
- * @func: pointer to function structure
- * @behind_bridge: 1 if this is a recursive call, 0 if not
- * @resources: pointer to set of resource lists
- *
- * Calls itself recursively for bridged devices.
- * Returns 0 if success
- *
- */
-static int
-configure_new_function(struct controller *ctrl, struct pci_func *func,
- u8 behind_bridge, struct resource_lists *resources,
- u8 bridge_bus, u8 bridge_dev)
-{
- int cloop;
- u8 temp_byte;
- u8 class_code;
- u32 rc;
- u32 temp_register;
- u32 base;
- unsigned int devfn;
- struct pci_resource *mem_node;
- struct pci_resource *io_node;
- struct pci_bus lpci_bus, *pci_bus;
-
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- /* Check for Bridge */
- rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
- if (rc)
- return rc;
- dbg("%s: bus %x dev %x func %x temp_byte = %x\n", __FUNCTION__,
- func->bus, func->device, func->function, temp_byte);
-
- if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
- rc = configure_new_bridge(ctrl, func, behind_bridge, resources,
- pci_bus);
-
- if (rc)
- return rc;
- } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
- /* Standard device */
- u64 base64;
- rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);
-
- if (class_code == PCI_BASE_CLASS_DISPLAY)
- return DEVICE_TYPE_NOT_SUPPORTED;
-
- /* Figure out IO and memory needs */
- for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
- temp_register = 0xFFFFFFFF;
-
- rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
- rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
- dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register,
- func->bus, func->device, func->function);
-
- if (!temp_register)
- continue;
-
- base64 = 0L;
- if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) {
- /* Map IO */
-
- /* set base = amount of IO space */
- base = temp_register & 0xFFFFFFFC;
- base = ~base + 1;
-
- dbg("NEED IO length(0x%x)\n", base);
- io_node = get_io_resource(&(resources->io_head),(ulong)base);
-
- /* allocate the resource to the board */
- if (io_node) {
- dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length);
- base = (u32)io_node->base;
- io_node->next = func->io_head;
- func->io_head = io_node;
- } else {
- err("Got NO IO resource(length=0x%x)\n", base);
- return -ENOMEM;
- }
- } else { /* map MEM */
- int prefetchable = 1;
- struct pci_resource **res_node = &func->p_mem_head;
- char *res_type_str = "PMEM";
- u32 temp_register2;
-
- if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) {
- prefetchable = 0;
- res_node = &func->mem_head;
- res_type_str++;
- }
-
- base = temp_register & 0xFFFFFFF0;
- base = ~base + 1;
-
- switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
- case PCI_BASE_ADDRESS_MEM_TYPE_32:
- dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base);
-
- if (prefetchable && resources->p_mem_head)
- mem_node=get_resource(&(resources->p_mem_head), (ulong)base);
- else {
- if (prefetchable)
- dbg("using MEM for PMEM\n");
- mem_node = get_resource(&(resources->mem_head), (ulong)base);
- }
-
- /* allocate the resource to the board */
- if (mem_node) {
- base = (u32)mem_node->base;
- mem_node->next = *res_node;
- *res_node = mem_node;
- dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base,
- mem_node->length);
- } else {
- err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base);
- return -ENOMEM;
- }
- break;
- case PCI_BASE_ADDRESS_MEM_TYPE_64:
- rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
- dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2,
- temp_register, base);
-
- if (prefetchable && resources->p_mem_head)
- mem_node = get_resource(&(resources->p_mem_head), (ulong)base);
- else {
- if (prefetchable)
- dbg("using MEM for PMEM\n");
- mem_node = get_resource(&(resources->mem_head), (ulong)base);
- }
-
- /* allocate the resource to the board */
- if (mem_node) {
- base64 = mem_node->base;
- mem_node->next = *res_node;
- *res_node = mem_node;
- dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32),
- (u32)base64, mem_node->length);
- } else {
- err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base);
- return -ENOMEM;
- }
- break;
- default:
- dbg("reserved BAR type=0x%x\n", temp_register);
- break;
- }
-
- }
-
- if (base64) {
- rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
- cloop += 4;
- base64 >>= 32;
-
- if (base64) {
- dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64);
- base64 = 0x0L;
- }
-
- rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
- } else {
- rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
- }
- } /* End of base register loop */
-
- /* disable ROM base Address */
- rc = pci_bus_write_config_dword (pci_bus, devfn, PCI_ROM_ADDRESS, 0x00);
-
- /* Set HP parameters (Cache Line Size, Latency Timer) */
- rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
- if (rc)
- return rc;
-
- pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL);
-
- dbg("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device,
- func->function);
- } /* End of Not-A-Bridge else */
- else {
- /* It's some strange type of PCI adapter (Cardbus?) */
- return DEVICE_TYPE_NOT_SUPPORTED;
- }
-
- func->configured = 1;
-
- return 0;
-}
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7a0e27f..2387e75 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -27,16 +27,12 @@
*
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
#include <linux/pci.h>
-#include <asm/system.h>
+#include <linux/interrupt.h>
+
#include "../pci.h"
#include "pciehp.h"
@@ -217,23 +213,6 @@ static int pcie_cap_base = 0; /* Base of the PCI Express capability item struct
#define MRL_STATE 0x0020
#define PRSN_STATE 0x0040
-struct php_ctlr_state_s {
- struct php_ctlr_state_s *pnext;
- struct pci_dev *pci_dev;
- unsigned int irq;
- unsigned long flags; /* spinlock's */
- u32 slot_device_offset;
- u32 num_slots;
- struct timer_list int_poll_timer; /* Added for poll event */
- php_intr_callback_t attention_button_callback;
- php_intr_callback_t switch_change_callback;
- php_intr_callback_t presence_change_callback;
- php_intr_callback_t power_fault_callback;
- void *callback_instance_id;
- struct ctrl_reg *creg; /* Ptr to controller register space */
-};
-
-
static spinlock_t hpc_event_lock;
DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
@@ -297,7 +276,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
DBG_ENTER_ROUTINE
- dbg("%s : Enter\n", __FUNCTION__);
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
@@ -308,7 +286,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return retval;
}
- dbg("%s : hp_register_read_word SLOT_STATUS %x\n", __FUNCTION__, slot_status);
if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) {
/* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue
@@ -316,14 +293,11 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
}
- dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE);
if (retval) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return retval;
}
- dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd | CMD_CMPL_INTR_ENABLE);
- dbg("%s : Exit\n", __FUNCTION__);
DBG_LEAVE_ROUTINE
return retval;
@@ -509,7 +483,6 @@ static int hpc_query_power_fault(struct slot * slot)
u16 slot_status;
u8 pwr_fault;
int retval = 0;
- u8 status;
DBG_ENTER_ROUTINE
@@ -521,15 +494,13 @@ static int hpc_query_power_fault(struct slot * slot)
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
if (retval) {
- err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+ err("%s : Cannot check for power fault\n", __FUNCTION__);
return retval;
}
pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
- status = (pwr_fault != 1) ? 1 : 0;
DBG_LEAVE_ROUTINE
- /* Note: Logic 0 => fault */
- return status;
+ return pwr_fault;
}
static int hpc_set_attention_status(struct slot *slot, u8 value)
@@ -539,7 +510,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
u16 slot_ctrl;
int rc = 0;
- dbg("%s: \n", __FUNCTION__);
+ DBG_ENTER_ROUTINE
+
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
@@ -555,7 +527,6 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return rc;
}
- dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
switch (value) {
case 0 : /* turn off */
@@ -576,6 +547,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+ DBG_LEAVE_ROUTINE
return rc;
}
@@ -587,7 +559,8 @@ static void hpc_set_green_led_on(struct slot *slot)
u16 slot_ctrl;
int rc = 0;
- dbg("%s: \n", __FUNCTION__);
+ DBG_ENTER_ROUTINE
+
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ;
@@ -604,7 +577,6 @@ static void hpc_set_green_led_on(struct slot *slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return;
}
- dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100;
if (!pciehp_poll_mode)
slot_cmd = slot_cmd | HP_INTR_ENABLE;
@@ -612,6 +584,7 @@ static void hpc_set_green_led_on(struct slot *slot)
pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+ DBG_LEAVE_ROUTINE
return;
}
@@ -622,7 +595,8 @@ static void hpc_set_green_led_off(struct slot *slot)
u16 slot_ctrl;
int rc = 0;
- dbg("%s: \n", __FUNCTION__);
+ DBG_ENTER_ROUTINE
+
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ;
@@ -639,7 +613,6 @@ static void hpc_set_green_led_off(struct slot *slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return;
}
- dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300;
@@ -648,6 +621,7 @@ static void hpc_set_green_led_off(struct slot *slot)
pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+ DBG_LEAVE_ROUTINE
return;
}
@@ -658,7 +632,8 @@ static void hpc_set_green_led_blink(struct slot *slot)
u16 slot_ctrl;
int rc = 0;
- dbg("%s: \n", __FUNCTION__);
+ DBG_ENTER_ROUTINE
+
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ;
@@ -675,7 +650,6 @@ static void hpc_set_green_led_blink(struct slot *slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return;
}
- dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200;
@@ -684,6 +658,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+ DBG_LEAVE_ROUTINE
return;
}
@@ -780,7 +755,6 @@ static int hpc_power_on_slot(struct slot * slot)
int retval = 0;
DBG_ENTER_ROUTINE
- dbg("%s: \n", __FUNCTION__);
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
@@ -799,8 +773,6 @@ static int hpc_power_on_slot(struct slot * slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval;
}
- dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
- slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
@@ -829,7 +801,6 @@ static int hpc_power_off_slot(struct slot * slot)
int retval = 0;
DBG_ENTER_ROUTINE
- dbg("%s: \n", __FUNCTION__);
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
@@ -848,8 +819,6 @@ static int hpc_power_off_slot(struct slot * slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval;
}
- dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
- slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
@@ -924,7 +893,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
return IRQ_NONE;
}
- dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__);
dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
@@ -933,7 +901,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE;
}
- dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) {
@@ -949,14 +916,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE;
}
- dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
}
if (intr_loc & CMD_COMPLETED) {
/*
* Command Complete Interrupt Pending
*/
- dbg("%s: In Command Complete Interrupt Pending\n", __FUNCTION__);
wake_up_interruptible(&ctrl->queue);
}
@@ -989,7 +954,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
}
dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);
- dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
@@ -997,14 +961,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE;
}
- dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE;
}
- dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
/* Clear command complete interrupt caused by this write */
temp_word = 0x1F;
@@ -1248,12 +1210,7 @@ static struct hpc_ops pciehp_hpc_ops = {
.check_lnk_status = hpc_check_lnk_status,
};
-int pcie_init(struct controller * ctrl,
- struct pcie_device *dev,
- php_intr_callback_t attention_button_callback,
- php_intr_callback_t switch_change_callback,
- php_intr_callback_t presence_change_callback,
- php_intr_callback_t power_fault_callback)
+int pcie_init(struct controller * ctrl, struct pcie_device *dev)
{
struct php_ctlr_state_s *php_ctlr, *p;
void *instance_id = ctrl;
@@ -1282,8 +1239,8 @@ int pcie_init(struct controller * ctrl,
pdev = dev->port;
php_ctlr->pci_dev = pdev; /* save pci_dev in context */
- dbg("%s: pdev->vendor %x pdev->device %x\n", __FUNCTION__,
- pdev->vendor, pdev->device);
+ dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n",
+ __FUNCTION__, pdev->vendor, pdev->device);
saved_cap_base = pcie_cap_base;
@@ -1340,8 +1297,6 @@ int pcie_init(struct controller * ctrl,
first = 0;
}
- dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
if (pci_resource_len(pdev, rc) > 0)
dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
@@ -1359,13 +1314,12 @@ int pcie_init(struct controller * ctrl,
/* find the IRQ */
php_ctlr->irq = dev->irq;
- dbg("HPC interrupt = %d\n", php_ctlr->irq);
/* Save interrupt callback info */
- php_ctlr->attention_button_callback = attention_button_callback;
- php_ctlr->switch_change_callback = switch_change_callback;
- php_ctlr->presence_change_callback = presence_change_callback;
- php_ctlr->power_fault_callback = power_fault_callback;
+ php_ctlr->attention_button_callback = pciehp_handle_attention_button;
+ php_ctlr->switch_change_callback = pciehp_handle_switch_change;
+ php_ctlr->presence_change_callback = pciehp_handle_presence_change;
+ php_ctlr->power_fault_callback = pciehp_handle_power_fault;
php_ctlr->callback_instance_id = instance_id;
/* return PCI Controller Info */
@@ -1387,15 +1341,12 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base)
- , slot_status);
temp_word = 0x1F; /* Clear all events */
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
@@ -1403,7 +1354,6 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
if (pciehp_poll_mode) {/* Install interrupt polling code */
/* Install and start the interrupt polling timer */
@@ -1419,13 +1369,14 @@ int pcie_init(struct controller * ctrl,
}
}
+ dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number,
+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
+
rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
- dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
intr_enable = intr_enable | PRSN_DETECT_ENABLE;
@@ -1445,7 +1396,6 @@ int pcie_init(struct controller * ctrl,
} else {
temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
}
- dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
/* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
@@ -1453,14 +1403,11 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__,
- SLOT_STATUS(ctrl->cap_base), slot_status);
temp_word = 0x1F; /* Clear all events */
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
@@ -1468,8 +1415,16 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
+ if (pciehp_force) {
+ dbg("Bypassing BIOS check for pciehp use on %s\n",
+ pci_name(ctrl->pci_dev));
+ } else {
+ rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
+ if (rc)
+ goto abort_free_ctlr;
+ }
+
/* Add this HPC instance into the HPC list */
spin_lock(&list_lock);
if (php_ctlr_list_head == 0) {
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index ff17d8e..647673a 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -27,801 +27,111 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/proc_fs.h>
#include <linux/pci.h>
#include "../pci.h"
#include "pciehp.h"
-#ifndef CONFIG_IA64
-#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */
-#endif
-int pciehp_configure_device (struct controller* ctrl, struct pci_func* func)
+int pciehp_configure_device(struct slot *p_slot)
{
- unsigned char bus;
- struct pci_bus *child;
- int num;
-
- if (func->pci_dev == NULL)
- func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
-
- /* Still NULL ? Well then scan for it ! */
- if (func->pci_dev == NULL) {
- dbg("%s: pci_dev still null. do pci_scan_slot\n", __FUNCTION__);
-
- num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function));
-
- if (num)
- pci_bus_add_devices(ctrl->pci_dev->subordinate);
-
- func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
- if (func->pci_dev == NULL) {
- dbg("ERROR: pci_dev still null\n");
- return 0;
- }
+ struct pci_dev *dev;
+ struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
+ int num, fn;
+
+ dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0));
+ if (dev) {
+ err("Device %s already exists at %x:%x, cannot hot-add\n",
+ pci_name(dev), p_slot->bus, p_slot->device);
+ return -EINVAL;
}
- if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
- pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
- child = pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
- pci_do_scan_bus(child);
+ num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
+ if (num == 0) {
+ err("No new device found\n");
+ return -ENODEV;
+ }
+ for (fn = 0; fn < 8; fn++) {
+ if (!(dev = pci_find_slot(p_slot->bus,
+ PCI_DEVFN(p_slot->device, fn))))
+ continue;
+ if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ err("Cannot hot-add display device %s\n",
+ pci_name(dev));
+ continue;
+ }
+ if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
+ (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
+ /* Find an unused bus number for the new bridge */
+ struct pci_bus *child;
+ unsigned char busnr, start = parent->secondary;
+ unsigned char end = parent->subordinate;
+ for (busnr = start; busnr <= end; busnr++) {
+ if (!pci_find_bus(pci_domain_nr(parent),
+ busnr))
+ break;
+ }
+ if (busnr >= end) {
+ err("No free bus for hot-added bridge\n");
+ continue;
+ }
+ child = pci_add_new_bus(parent, dev, busnr);
+ if (!child) {
+ err("Cannot add new bus for %s\n",
+ pci_name(dev));
+ continue;
+ }
+ child->subordinate = pci_do_scan_bus(child);
+ pci_bus_size_bridges(child);
+ }
+ /* TBD: program firmware provided _HPP values */
+ /* program_fw_provided_values(dev); */
}
+ pci_bus_assign_resources(parent);
+ pci_bus_add_devices(parent);
+ pci_enable_bridges(parent);
return 0;
}
-
-int pciehp_unconfigure_device(struct pci_func* func)
+int pciehp_unconfigure_device(struct slot *p_slot)
{
int rc = 0;
int j;
- struct pci_bus *pbus;
+ u8 bctl = 0;
- dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus,
- func->device, func->function);
- pbus = func->pci_dev->bus;
+ dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus,
+ p_slot->device);
for (j=0; j<8 ; j++) {
- struct pci_dev* temp = pci_find_slot(func->bus,
- (func->device << 3) | j);
- if (temp) {
- pci_remove_bus_device(temp);
+ struct pci_dev* temp = pci_find_slot(p_slot->bus,
+ (p_slot->device << 3) | j);
+ if (!temp)
+ continue;
+ if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ err("Cannot remove display device %s\n",
+ pci_name(temp));
+ continue;
}
+ if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
+ if (bctl & PCI_BRIDGE_CTL_VGA) {
+ err("Cannot remove display device %s\n",
+ pci_name(temp));
+ continue;
+ }
+ }
+ pci_remove_bus_device(temp);
}
/*
* Some PCI Express root ports require fixup after hot-plug operation.
*/
if (pcie_mch_quirk)
- pci_fixup_device(pci_fixup_final, pbus->self);
+ pci_fixup_device(pci_fixup_final, p_slot->ctrl->pci_dev);
return rc;
}
-/*
- * pciehp_set_irq
- *
- * @bus_num: bus number of PCI device
- * @dev_num: device number of PCI device
- * @slot: pointer to u8 where slot number will be returned
- */
-int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
-{
-#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_IO_APIC)
- int rc;
- u16 temp_word;
- struct pci_dev fakedev;
- struct pci_bus fakebus;
-
- fakedev.devfn = dev_num << 3;
- fakedev.bus = &fakebus;
- fakebus.number = bus_num;
- dbg("%s: dev %d, bus %d, pin %d, num %d\n",
- __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
- rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
- dbg("%s: rc %d\n", __FUNCTION__, rc);
- if (!rc)
- return !rc;
-
- /* set the Edge Level Control Register (ELCR) */
- temp_word = inb(0x4d0);
- temp_word |= inb(0x4d1) << 8;
-
- temp_word |= 0x01 << irq_num;
-
- /* This should only be for x86 as it sets the Edge Level Control Register */
- outb((u8) (temp_word & 0xFF), 0x4d0);
- outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
-#endif
- return 0;
-}
-
-/* More PCI configuration routines; this time centered around hotplug controller */
-
-
-/*
- * pciehp_save_config
- *
- * Reads configuration for all slots in a PCI bus and saves info.
- *
- * Note: For non-hot plug busses, the slot # saved is the device #
- *
- * returns 0 if success
- */
-int pciehp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
-{
- int rc;
- u8 class_code;
- u8 header_type;
- u32 ID;
- u8 secondary_bus;
- struct pci_func *new_slot;
- int sub_bus;
- int max_functions;
- int function;
- u8 DevError;
- int device = 0;
- int cloop = 0;
- int stop_it;
- int index;
- int is_hot_plug = num_ctlr_slots || first_device_num;
- struct pci_bus lpci_bus, *pci_bus;
- int FirstSupported, LastSupported;
-
- dbg("%s: Enter\n", __FUNCTION__);
-
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
-
- dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
- num_ctlr_slots, first_device_num);
-
- /* Decide which slots are supported */
- if (is_hot_plug) {
- /*********************************
- * is_hot_plug is the slot mask
- *********************************/
- FirstSupported = first_device_num;
- LastSupported = FirstSupported + num_ctlr_slots - 1;
- } else {
- FirstSupported = 0;
- LastSupported = 0x1F;
- }
-
- dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported,
- LastSupported);
-
- /* Save PCI configuration space for all devices in supported slots */
- dbg("%s: pci_bus->number = %x\n", __FUNCTION__, pci_bus->number);
- pci_bus->number = busnumber;
- dbg("%s: bus = %x, dev = %x\n", __FUNCTION__, busnumber, device);
- for (device = FirstSupported; device <= LastSupported; device++) {
- ID = 0xFFFFFFFF;
- rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
- PCI_VENDOR_ID, &ID);
-
- if (ID != 0xFFFFFFFF) { /* device in slot */
- dbg("%s: ID = %x\n", __FUNCTION__, ID);
- rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
- 0x0B, &class_code);
- if (rc)
- return rc;
-
- rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
- PCI_HEADER_TYPE, &header_type);
- if (rc)
- return rc;
-
- dbg("class_code = %x, header_type = %x\n", class_code, header_type);
-
- /* If multi-function device, set max_functions to 8 */
- if (header_type & 0x80)
- max_functions = 8;
- else
- max_functions = 1;
-
- function = 0;
-
- do {
- DevError = 0;
- dbg("%s: In do loop\n", __FUNCTION__);
-
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* P-P Bridge */
- /* Recurse the subordinate bus
- * get the subordinate bus number
- */
- rc = pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(device, function),
- PCI_SECONDARY_BUS, &secondary_bus);
- if (rc) {
- return rc;
- } else {
- sub_bus = (int) secondary_bus;
-
- /* Save secondary bus cfg spc with this recursive call. */
- rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
- if (rc)
- return rc;
- }
- }
-
- index = 0;
- new_slot = pciehp_slot_find(busnumber, device, index++);
-
- dbg("%s: new_slot = %p bus %x dev %x fun %x\n",
- __FUNCTION__, new_slot, busnumber, device, index-1);
-
- while (new_slot && (new_slot->function != (u8) function)) {
- new_slot = pciehp_slot_find(busnumber, device, index++);
- dbg("%s: while loop, new_slot = %p bus %x dev %x fun %x\n",
- __FUNCTION__, new_slot, busnumber, device, index-1);
- }
- if (!new_slot) {
- /* Setup slot structure. */
- new_slot = pciehp_slot_create(busnumber);
- dbg("%s: if, new_slot = %p bus %x dev %x fun %x\n",
- __FUNCTION__, new_slot, busnumber, device, function);
-
- if (new_slot == NULL)
- return(1);
- }
-
- new_slot->bus = (u8) busnumber;
- new_slot->device = (u8) device;
- new_slot->function = (u8) function;
- new_slot->is_a_board = 1;
- new_slot->switch_save = 0x10;
- /* In case of unsupported board */
- new_slot->status = DevError;
- new_slot->pci_dev = pci_find_slot(new_slot->bus,
- (new_slot->device << 3) | new_slot->function);
- dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
-
- for (cloop = 0; cloop < 0x20; cloop++) {
- rc = pci_bus_read_config_dword(pci_bus,
- PCI_DEVFN(device, function),
- cloop << 2,
- (u32 *) &(new_slot->config_space [cloop]));
- /* dbg("new_slot->config_space[%x] = %x\n",
- cloop, new_slot->config_space[cloop]); */
- if (rc)
- return rc;
- }
-
- function++;
-
- stop_it = 0;
-
- /* this loop skips to the next present function
- * reading in Class Code and Header type.
- */
-
- while ((function < max_functions)&&(!stop_it)) {
- dbg("%s: In while loop \n", __FUNCTION__);
- rc = pci_bus_read_config_dword(pci_bus,
- PCI_DEVFN(device, function),
- PCI_VENDOR_ID, &ID);
-
- if (ID == 0xFFFFFFFF) { /* nothing there. */
- function++;
- dbg("Nothing there\n");
- } else { /* Something there */
- rc = pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(device, function),
- 0x0B, &class_code);
- if (rc)
- return rc;
-
- rc = pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(device, function),
- PCI_HEADER_TYPE, &header_type);
- if (rc)
- return rc;
-
- dbg("class_code = %x, header_type = %x\n", class_code, header_type);
- stop_it++;
- }
- }
-
- } while (function < max_functions);
- /* End of IF (device in slot?) */
- } else if (is_hot_plug) {
- /* Setup slot structure with entry for empty slot */
- new_slot = pciehp_slot_create(busnumber);
-
- if (new_slot == NULL) {
- return(1);
- }
- dbg("new_slot = %p, bus = %x, dev = %x, fun = %x\n", new_slot,
- new_slot->bus, new_slot->device, new_slot->function);
-
- new_slot->bus = (u8) busnumber;
- new_slot->device = (u8) device;
- new_slot->function = 0;
- new_slot->is_a_board = 0;
- new_slot->presence_save = 0;
- new_slot->switch_save = 0;
- }
- } /* End of FOR loop */
-
- dbg("%s: Exit\n", __FUNCTION__);
- return(0);
-}
-
-
-/*
- * pciehp_save_slot_config
- *
- * Saves configuration info for all PCI devices in a given slot
- * including subordinate busses.
- *
- * returns 0 if success
- */
-int pciehp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot)
-{
- int rc;
- u8 class_code;
- u8 header_type;
- u32 ID;
- u8 secondary_bus;
- int sub_bus;
- int max_functions;
- int function;
- int cloop = 0;
- int stop_it;
- struct pci_bus lpci_bus, *pci_bus;
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = new_slot->bus;
-
- ID = 0xFFFFFFFF;
-
- pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0),
- PCI_VENDOR_ID, &ID);
-
- if (ID != 0xFFFFFFFF) { /* device in slot */
- pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
- 0x0B, &class_code);
-
- pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
- PCI_HEADER_TYPE, &header_type);
-
- if (header_type & 0x80) /* Multi-function device */
- max_functions = 8;
- else
- max_functions = 1;
-
- function = 0;
-
- do {
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
- /* Recurse the subordinate bus */
- pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- PCI_SECONDARY_BUS, &secondary_bus);
-
- sub_bus = (int) secondary_bus;
-
- /* Save the config headers for the secondary bus. */
- rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
-
- if (rc)
- return rc;
-
- } /* End of IF */
-
- new_slot->status = 0;
-
- for (cloop = 0; cloop < 0x20; cloop++) {
- pci_bus_read_config_dword(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- cloop << 2,
- (u32 *) &(new_slot->config_space [cloop]));
- }
-
- function++;
-
- stop_it = 0;
-
- /* this loop skips to the next present function
- * reading in the Class Code and the Header type.
- */
-
- while ((function < max_functions) && (!stop_it)) {
- pci_bus_read_config_dword(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- PCI_VENDOR_ID, &ID);
-
- if (ID == 0xFFFFFFFF) { /* nothing there. */
- function++;
- } else { /* Something there */
- pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- 0x0B, &class_code);
-
- pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- PCI_HEADER_TYPE, &header_type);
-
- stop_it++;
- }
- }
-
- } while (function < max_functions);
- } /* End of IF (device in slot?) */
- else {
- return 2;
- }
-
- return 0;
-}
-
-
-/*
- * pciehp_save_used_resources
- *
- * Stores used resource information for existing boards. this is
- * for boards that were in the system when this driver was loaded.
- * this function is for hot plug ADD
- *
- * returns 0 if success
- * if disable == 1(DISABLE_CARD),
- * it loops for all functions of the slot and disables them.
- * else, it just get resources of the function and return.
- */
-int pciehp_save_used_resources(struct controller *ctrl, struct pci_func *func, int disable)
-{
- u8 cloop;
- u8 header_type;
- u8 secondary_bus;
- u8 temp_byte;
- u16 command;
- u16 save_command;
- u16 w_base, w_length;
- u32 temp_register;
- u32 save_base;
- u32 base, length;
- u64 base64 = 0;
- int index = 0;
- unsigned int devfn;
- struct pci_resource *mem_node = NULL;
- struct pci_resource *p_mem_node = NULL;
- struct pci_resource *t_mem_node;
- struct pci_resource *io_node;
- struct pci_resource *bus_node;
- struct pci_bus lpci_bus, *pci_bus;
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
-
- if (disable)
- func = pciehp_slot_find(func->bus, func->device, index++);
-
- while ((func != NULL) && func->is_a_board) {
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- /* Save the command register */
- pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
-
- if (disable) {
- /* disable card */
- command = 0x00;
- pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
- }
-
- /* Check for Bridge */
- pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
-
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
- dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n",
- func->bus, func->device, save_command);
- if (disable) {
- /* Clear Bridge Control Register */
- command = 0x00;
- pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
- }
-
- pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
- pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
-
- bus_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!bus_node)
- return -ENOMEM;
-
- bus_node->base = (ulong)secondary_bus;
- bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
-
- bus_node->next = func->bus_head;
- func->bus_head = bus_node;
-
- /* Save IO base and Limit registers */
- pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &temp_byte);
- base = temp_byte;
- pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
- length = temp_byte;
-
- if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
- io_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!io_node)
- return -ENOMEM;
-
- io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
- io_node->length = (ulong)(length - base + 0x10) << 8;
-
- io_node->next = func->io_head;
- func->io_head = io_node;
- }
-
- /* Save memory base and Limit registers */
- pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
- pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
-
- if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
- mem_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!mem_node)
- return -ENOMEM;
-
- mem_node->base = (ulong)w_base << 16;
- mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
-
- mem_node->next = func->mem_head;
- func->mem_head = mem_node;
- }
- /* Save prefetchable memory base and Limit registers */
- pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
- pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
-
- if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
- p_mem_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!p_mem_node)
- return -ENOMEM;
-
- p_mem_node->base = (ulong)w_base << 16;
- p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
-
- p_mem_node->next = func->p_mem_head;
- func->p_mem_head = p_mem_node;
- }
- } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
- dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n",
- func->bus, func->device, save_command);
-
- /* Figure out IO and memory base lengths */
- for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
- pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
-
- temp_register = 0xFFFFFFFF;
- pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
- pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
-
- if (!disable)
- pci_bus_write_config_dword(pci_bus, devfn, cloop, save_base);
-
- if (!temp_register)
- continue;
-
- base = temp_register;
-
- if ((base & PCI_BASE_ADDRESS_SPACE_IO) &&
- (!disable || (save_command & PCI_COMMAND_IO))) {
- /* IO base */
- /* set temp_register = amount of IO space requested */
- base = base & 0xFFFFFFFCL;
- base = (~base) + 1;
-
- io_node = kmalloc(sizeof (struct pci_resource),
- GFP_KERNEL);
- if (!io_node)
- return -ENOMEM;
-
- io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
- io_node->length = (ulong)base;
- dbg("sur adapter: IO bar=0x%x(length=0x%x)\n",
- io_node->base, io_node->length);
-
- io_node->next = func->io_head;
- func->io_head = io_node;
- } else { /* map Memory */
- int prefetchable = 1;
- /* struct pci_resources **res_node; */
- char *res_type_str = "PMEM";
- u32 temp_register2;
-
- t_mem_node = kmalloc(sizeof (struct pci_resource),
- GFP_KERNEL);
- if (!t_mem_node)
- return -ENOMEM;
-
- if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
- (!disable || (save_command & PCI_COMMAND_MEMORY))) {
- prefetchable = 0;
- mem_node = t_mem_node;
- res_type_str++;
- } else
- p_mem_node = t_mem_node;
-
- base = base & 0xFFFFFFF0L;
- base = (~base) + 1;
-
- switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
- case PCI_BASE_ADDRESS_MEM_TYPE_32:
- if (prefetchable) {
- p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
- p_mem_node->length = (ulong)base;
- dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
- res_type_str,
- p_mem_node->base,
- p_mem_node->length);
-
- p_mem_node->next = func->p_mem_head;
- func->p_mem_head = p_mem_node;
- } else {
- mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
- mem_node->length = (ulong)base;
- dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
- res_type_str,
- mem_node->base,
- mem_node->length);
-
- mem_node->next = func->mem_head;
- func->mem_head = mem_node;
- }
- break;
- case PCI_BASE_ADDRESS_MEM_TYPE_64:
- pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
- base64 = temp_register2;
- base64 = (base64 << 32) | save_base;
-
- if (temp_register2) {
- dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n",
- res_type_str, temp_register2, (u32)base64);
- base64 &= 0x00000000FFFFFFFFL;
- }
-
- if (prefetchable) {
- p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
- p_mem_node->length = base;
- dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
- res_type_str,
- p_mem_node->base,
- p_mem_node->length);
-
- p_mem_node->next = func->p_mem_head;
- func->p_mem_head = p_mem_node;
- } else {
- mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
- mem_node->length = base;
- dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
- res_type_str,
- mem_node->base,
- mem_node->length);
-
- mem_node->next = func->mem_head;
- func->mem_head = mem_node;
- }
- cloop += 4;
- break;
- default:
- dbg("asur: reserved BAR type=0x%x\n",
- temp_register);
- break;
- }
- }
- } /* End of base register loop */
- } else { /* Some other unknown header type */
- dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n",
- func->bus, func->device);
- }
-
- /* find the next device in this slot */
- if (!disable)
- break;
- func = pciehp_slot_find(func->bus, func->device, index++);
- }
-
- return 0;
-}
-
-
-/**
- * kfree_resource_list: release memory of all list members
- * @res: resource list to free
- */
-static inline void
-return_resource_list(struct pci_resource **func, struct pci_resource **res)
-{
- struct pci_resource *node;
- struct pci_resource *t_node;
-
- node = *func;
- *func = NULL;
- while (node) {
- t_node = node->next;
- return_resource(res, node);
- node = t_node;
- }
-}
-
-/*
- * pciehp_return_board_resources
- *
- * this routine returns all resources allocated to a board to
- * the available pool.
- *
- * returns 0 if success
- */
-int pciehp_return_board_resources(struct pci_func * func,
- struct resource_lists * resources)
-{
- int rc;
-
- dbg("%s\n", __FUNCTION__);
-
- if (!func)
- return 1;
-
- return_resource_list(&(func->io_head),&(resources->io_head));
- return_resource_list(&(func->mem_head),&(resources->mem_head));
- return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
- return_resource_list(&(func->bus_head),&(resources->bus_head));
-
- rc = pciehp_resource_sort_and_combine(&(resources->mem_head));
- rc |= pciehp_resource_sort_and_combine(&(resources->p_mem_head));
- rc |= pciehp_resource_sort_and_combine(&(resources->io_head));
- rc |= pciehp_resource_sort_and_combine(&(resources->bus_head));
-
- return rc;
-}
-
-/**
- * kfree_resource_list: release memory of all list members
- * @res: resource list to free
- */
-static inline void
-kfree_resource_list(struct pci_resource **r)
-{
- struct pci_resource *res, *tres;
-
- res = *r;
- *r = NULL;
-
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-}
-
-/**
- * pciehp_destroy_resource_list: put node back in the resource list
- * @resources: list to put nodes back
- */
-void pciehp_destroy_resource_list(struct resource_lists * resources)
-{
- kfree_resource_list(&(resources->io_head));
- kfree_resource_list(&(resources->mem_head));
- kfree_resource_list(&(resources->p_mem_head));
- kfree_resource_list(&(resources->bus_head));
-}
-
-/**
- * pciehp_destroy_board_resources: put node back in the resource list
- * @resources: list to put nodes back
- */
-void pciehp_destroy_board_resources(struct pci_func * func)
-{
- kfree_resource_list(&(func->io_head));
- kfree_resource_list(&(func->mem_head));
- kfree_resource_list(&(func->p_mem_head));
- kfree_resource_list(&(func->bus_head));
-}
diff --git a/drivers/pci/hotplug/pciehprm.h b/drivers/pci/hotplug/pciehprm.h
deleted file mode 100644
index 05f20fb..0000000
--- a/drivers/pci/hotplug/pciehprm.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * PCIEHPRM : PCIEHP Resource Manager for ACPI/non-ACPI platform
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2003-2004 Intel Corporation
- *
- * All rights reserved.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT. 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.
- *
- * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
- *
- */
-
-#ifndef _PCIEHPRM_H_
-#define _PCIEHPRM_H_
-
-#ifdef CONFIG_HOTPLUG_PCI_PCIE_PHPRM_NONACPI
-#include "pciehprm_nonacpi.h"
-#endif
-
-int pciehprm_init(enum php_ctlr_type ct);
-void pciehprm_cleanup(void);
-int pciehprm_print_pirt(void);
-int pciehprm_find_available_resources(struct controller *ctrl);
-int pciehprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
-void pciehprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
-
-#ifdef DEBUG
-#define RES_CHECK(this, bits) \
- { if (((this) & (bits - 1))) \
- printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
-#else
-#define RES_CHECK(this, bits)
-#endif
-
-#endif /* _PCIEHPRM_H_ */
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
index 1406db3..ae244e2 100644
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -24,100 +24,20 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
-#include <linux/init.h>
#include <linux/acpi.h>
-#include <linux/efi.h>
#include <linux/pci-acpi.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#ifdef CONFIG_IA64
-#include <asm/iosapic.h>
-#endif
-#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/actypes.h>
#include "pciehp.h"
-#include "pciehprm.h"
-
-#define PCI_MAX_BUS 0x100
-#define ACPI_STA_DEVICE_PRESENT 0x01
#define METHOD_NAME__SUN "_SUN"
#define METHOD_NAME__HPP "_HPP"
#define METHOD_NAME_OSHP "OSHP"
-/* Status code for running acpi method to gain native control */
-#define NC_NOT_RUN 0
-#define OSC_NOT_EXIST 1
-#define OSC_RUN_FAILED 2
-#define OSHP_NOT_EXIST 3
-#define OSHP_RUN_FAILED 4
-#define NC_RUN_SUCCESS 5
-
-#define PHP_RES_BUS 0xA0
-#define PHP_RES_IO 0xA1
-#define PHP_RES_MEM 0xA2
-#define PHP_RES_PMEM 0xA3
-
-#define BRIDGE_TYPE_P2P 0x00
-#define BRIDGE_TYPE_HOST 0x01
-
-/* this should go to drivers/acpi/include/ */
-struct acpi__hpp {
- u8 cache_line_size;
- u8 latency_timer;
- u8 enable_serr;
- u8 enable_perr;
-};
-
-struct acpi_php_slot {
- struct acpi_php_slot *next;
- struct acpi_bridge *bridge;
- acpi_handle handle;
- int seg;
- int bus;
- int dev;
- int fun;
- u32 sun;
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
- void *slot_ops; /* _STA, _EJx, etc */
- struct slot *slot;
-}; /* per func */
-
-struct acpi_bridge {
- struct acpi_bridge *parent;
- struct acpi_bridge *next;
- struct acpi_bridge *child;
- acpi_handle handle;
- int seg;
- int pbus; /* pdev->bus->number */
- int pdevice; /* PCI_SLOT(pdev->devfn) */
- int pfunction; /* PCI_DEVFN(pdev->devfn) */
- int bus; /* pdev->subordinate->number */
- struct acpi__hpp *_hpp;
- struct acpi_php_slot *slots;
- struct pci_resource *tmem_head; /* total from crs */
- struct pci_resource *tp_mem_head; /* total from crs */
- struct pci_resource *tio_head; /* total from crs */
- struct pci_resource *tbus_head; /* total from crs */
- struct pci_resource *mem_head; /* available */
- struct pci_resource *p_mem_head; /* available */
- struct pci_resource *io_head; /* available */
- struct pci_resource *bus_head; /* available */
- int scanned;
- int type;
-};
-
-static struct acpi_bridge *acpi_bridges_head;
-
static u8 * acpi_path_name( acpi_handle handle)
{
acpi_status status;
@@ -133,85 +53,43 @@ static u8 * acpi_path_name( acpi_handle handle)
return path_name;
}
-static void acpi_get__hpp ( struct acpi_bridge *ab);
-static int acpi_run_oshp ( struct acpi_bridge *ab);
-static int osc_run_status = NC_NOT_RUN;
-static int oshp_run_status = NC_NOT_RUN;
-
-static int acpi_add_slot_to_php_slots(
- struct acpi_bridge *ab,
- int bus_num,
- acpi_handle handle,
- u32 adr,
- u32 sun
- )
-{
- struct acpi_php_slot *aps;
- static long samesun = -1;
-
- aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
- if (!aps) {
- err ("acpi_pciehprm: alloc for aps fail\n");
- return -1;
- }
- memset(aps, 0, sizeof(struct acpi_php_slot));
-
- aps->handle = handle;
- aps->bus = bus_num;
- aps->dev = (adr >> 16) & 0xffff;
- aps->fun = adr & 0xffff;
- aps->sun = sun;
-
- aps->next = ab->slots; /* cling to the bridge */
- aps->bridge = ab;
- ab->slots = aps;
-
- ab->scanned += 1;
- if (!ab->_hpp)
- acpi_get__hpp(ab);
-
- if (osc_run_status == OSC_NOT_EXIST)
- oshp_run_status = acpi_run_oshp(ab);
-
- if (sun != samesun) {
- info("acpi_pciehprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n",
- aps->sun, ab->seg, aps->bus, aps->dev, aps->fun);
- samesun = sun;
- }
- return 0;
-}
-
-static void acpi_get__hpp ( struct acpi_bridge *ab)
+static acpi_status
+acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
{
acpi_status status;
u8 nui[4];
struct acpi_buffer ret_buf = { 0, NULL};
union acpi_object *ext_obj, *package;
- u8 *path_name = acpi_path_name(ab->handle);
+ u8 *path_name = acpi_path_name(handle);
int i, len = 0;
/* get _hpp */
- status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
+ status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
switch (status) {
case AE_BUFFER_OVERFLOW:
ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
if (!ret_buf.pointer) {
- err ("acpi_pciehprm:%s alloc for _HPP fail\n", path_name);
- return;
+ err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
+ path_name);
+ return AE_NO_MEMORY;
}
- status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
+ status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
+ NULL, &ret_buf);
if (ACPI_SUCCESS(status))
break;
default:
if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s _HPP fail=0x%x\n", path_name, status);
- return;
+ dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
+ path_name, status);
+ return status;
}
}
ext_obj = (union acpi_object *) ret_buf.pointer;
if (ext_obj->type != ACPI_TYPE_PACKAGE) {
- err ("acpi_pciehprm:%s _HPP obj not a package\n", path_name);
+ err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
+ path_name);
+ status = AE_ERROR;
goto free_and_return;
}
@@ -224,1514 +102,153 @@ static void acpi_get__hpp ( struct acpi_bridge *ab)
nui[i] = (u8)ext_obj->integer.value;
break;
default:
- err ("acpi_pciehprm:%s _HPP obj type incorrect\n", path_name);
+ err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
+ path_name);
+ status = AE_ERROR;
goto free_and_return;
}
}
- ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
- if (!ab->_hpp) {
- err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name);
- goto free_and_return;
- }
- memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
+ hpp->cache_line_size = nui[0];
+ hpp->latency_timer = nui[1];
+ hpp->enable_serr = nui[2];
+ hpp->enable_perr = nui[3];
- ab->_hpp->cache_line_size = nui[0];
- ab->_hpp->latency_timer = nui[1];
- ab->_hpp->enable_serr = nui[2];
- ab->_hpp->enable_perr = nui[3];
-
- dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
- dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
- dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
- dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
+ dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
+ dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
+ dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
+ dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
free_and_return:
kfree(ret_buf.pointer);
+ return status;
}
-static int acpi_run_oshp ( struct acpi_bridge *ab)
+static acpi_status acpi_run_oshp(acpi_handle handle)
{
acpi_status status;
- u8 *path_name = acpi_path_name(ab->handle);
+ u8 *path_name = acpi_path_name(handle);
/* run OSHP */
- status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
+ status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
- oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED;
+ dbg("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
+ status);
} else {
- oshp_run_status = NC_RUN_SUCCESS;
- dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
- dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status);
- }
- return oshp_run_status;
-}
-
-static acpi_status acpi_evaluate_crs(
- acpi_handle handle,
- struct acpi_resource **retbuf
- )
-{
- acpi_status status;
- struct acpi_buffer crsbuf;
- u8 *path_name = acpi_path_name(handle);
-
- crsbuf.length = 0;
- crsbuf.pointer = NULL;
-
- status = acpi_get_current_resources (handle, &crsbuf);
-
- switch (status) {
- case AE_BUFFER_OVERFLOW:
- break; /* found */
- case AE_NOT_FOUND:
- dbg("acpi_pciehprm:%s _CRS not found\n", path_name);
- return status;
- default:
- err ("acpi_pciehprm:%s _CRS fail=0x%x\n", path_name, status);
- return status;
+ dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
}
-
- crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL);
- if (!crsbuf.pointer) {
- err ("acpi_pciehprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name);
- return AE_NO_MEMORY;
- }
-
- status = acpi_get_current_resources (handle, &crsbuf);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm: %s _CRS fail=0x%x.\n", path_name, status);
- kfree(crsbuf.pointer);
- return status;
- }
-
- *retbuf = crsbuf.pointer;
-
return status;
}
-static void free_pci_resource ( struct pci_resource *aprh)
+static int is_root_bridge(acpi_handle handle)
{
- struct pci_resource *res, *next;
+ acpi_status status;
+ struct acpi_device_info *info;
+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ int i;
- for (res = aprh; res; res = next) {
- next = res->next;
- kfree(res);
- }
-}
-
-static void print_pci_resource ( struct pci_resource *aprh)
-{
- struct pci_resource *res;
-
- for (res = aprh; res; res = res->next)
- dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
-}
-
-static void print_slot_resources( struct acpi_php_slot *aps)
-{
- if (aps->bus_head) {
- dbg(" BUS Resources:\n");
- print_pci_resource (aps->bus_head);
- }
-
- if (aps->io_head) {
- dbg(" IO Resources:\n");
- print_pci_resource (aps->io_head);
- }
-
- if (aps->mem_head) {
- dbg(" MEM Resources:\n");
- print_pci_resource (aps->mem_head);
- }
-
- if (aps->p_mem_head) {
- dbg(" PMEM Resources:\n");
- print_pci_resource (aps->p_mem_head);
- }
-}
-
-static void print_pci_resources( struct acpi_bridge *ab)
-{
- if (ab->tbus_head) {
- dbg(" Total BUS Resources:\n");
- print_pci_resource (ab->tbus_head);
- }
- if (ab->bus_head) {
- dbg(" BUS Resources:\n");
- print_pci_resource (ab->bus_head);
- }
-
- if (ab->tio_head) {
- dbg(" Total IO Resources:\n");
- print_pci_resource (ab->tio_head);
- }
- if (ab->io_head) {
- dbg(" IO Resources:\n");
- print_pci_resource (ab->io_head);
- }
-
- if (ab->tmem_head) {
- dbg(" Total MEM Resources:\n");
- print_pci_resource (ab->tmem_head);
- }
- if (ab->mem_head) {
- dbg(" MEM Resources:\n");
- print_pci_resource (ab->mem_head);
- }
-
- if (ab->tp_mem_head) {
- dbg(" Total PMEM Resources:\n");
- print_pci_resource (ab->tp_mem_head);
- }
- if (ab->p_mem_head) {
- dbg(" PMEM Resources:\n");
- print_pci_resource (ab->p_mem_head);
- }
- if (ab->_hpp) {
- dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
- dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
- dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
- dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
- }
-}
-
-static int pciehprm_delete_resource(
- struct pci_resource **aprh,
- ulong base,
- ulong size)
-{
- struct pci_resource *res;
- struct pci_resource *prevnode;
- struct pci_resource *split_node;
- ulong tbase;
-
- pciehp_resource_sort_and_combine(aprh);
-
- for (res = *aprh; res; res = res->next) {
- if (res->base > base)
- continue;
-
- if ((res->base + res->length) < (base + size))
- continue;
-
- if (res->base < base) {
- tbase = base;
-
- if ((res->length - (tbase - res->base)) < size)
- continue;
-
- split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base;
- split_node->length = tbase - res->base;
- res->base = tbase;
- res->length -= split_node->length;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (res->length >= size) {
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base + size;
- split_node->length = res->length - size;
- res->length = size;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (*aprh == res) {
- *aprh = res->next;
- } else {
- prevnode = *aprh;
- while (prevnode->next != res)
- prevnode = prevnode->next;
-
- prevnode->next = res->next;
- }
- res->next = NULL;
- kfree(res);
- break;
- }
-
- return 0;
-}
-
-static int pciehprm_delete_resources(
- struct pci_resource **aprh,
- struct pci_resource *this
- )
-{
- struct pci_resource *res;
-
- for (res = this; res; res = res->next)
- pciehprm_delete_resource(aprh, res->base, res->length);
-
- return 0;
-}
-
-static int pciehprm_add_resource(
- struct pci_resource **aprh,
- ulong base,
- ulong size)
-{
- struct pci_resource *res;
-
- for (res = *aprh; res; res = res->next) {
- if ((res->base + res->length) == base) {
- res->length += size;
- size = 0L;
- break;
+ status = acpi_get_object_info(handle, &buffer);
+ if (ACPI_SUCCESS(status)) {
+ info = buffer.pointer;
+ if ((info->valid & ACPI_VALID_HID) &&
+ !strcmp(PCI_ROOT_HID_STRING,
+ info->hardware_id.value)) {
+ acpi_os_free(buffer.pointer);
+ return 1;
+ }
+ if (info->valid & ACPI_VALID_CID) {
+ for (i=0; i < info->compatibility_id.count; i++) {
+ if (!strcmp(PCI_ROOT_HID_STRING,
+ info->compatibility_id.id[i].value)) {
+ acpi_os_free(buffer.pointer);
+ return 1;
+ }
+ }
}
- if (res->next == *aprh)
- break;
}
-
- if (size) {
- res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!res) {
- err ("acpi_pciehprm: alloc for res fail\n");
- return -ENOMEM;
- }
- memset(res, 0, sizeof (struct pci_resource));
-
- res->base = base;
- res->length = size;
- res->next = *aprh;
- *aprh = res;
- }
-
return 0;
}
-static int pciehprm_add_resources(
- struct pci_resource **aprh,
- struct pci_resource *this
- )
-{
- struct pci_resource *res;
- int rc = 0;
-
- for (res = this; res && !rc; res = res->next)
- rc = pciehprm_add_resource(aprh, res->base, res->length);
-
- return rc;
-}
-
-static void acpi_parse_io (
- struct acpi_bridge *ab,
- union acpi_resource_data *data
- )
+int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
- struct acpi_resource_io *dataio;
- dataio = (struct acpi_resource_io *) data;
-
- dbg("Io Resource\n");
- dbg(" %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10);
- dbg(" Range minimum base: %08X\n", dataio->min_base_address);
- dbg(" Range maximum base: %08X\n", dataio->max_base_address);
- dbg(" Alignment: %08X\n", dataio->alignment);
- dbg(" Range Length: %08X\n", dataio->range_length);
-}
-
-static void acpi_parse_fixed_io (
- struct acpi_bridge *ab,
- union acpi_resource_data *data
- )
-{
- struct acpi_resource_fixed_io *datafio;
- datafio = (struct acpi_resource_fixed_io *) data;
-
- dbg("Fixed Io Resource\n");
- dbg(" Range base address: %08X", datafio->base_address);
- dbg(" Range length: %08X", datafio->range_length);
-}
-
-static void acpi_parse_address16_32 (
- struct acpi_bridge *ab,
- union acpi_resource_data *data,
- acpi_resource_type id
- )
-{
- /*
- * acpi_resource_address16 == acpi_resource_address32
- * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
+ acpi_status status;
+ acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
+ struct pci_dev *pdev = dev;
+ u8 *path_name;
+ /*
+ * Per PCI firmware specification, we should run the ACPI _OSC
+ * method to get control of hotplug hardware before using it.
+ * If an _OSC is missing, we look for an OSHP to do the same thing.
+ * To handle different BIOS behavior, we look for _OSC and OSHP
+ * within the scope of the hotplug controller and its parents, upto
+ * the host bridge under which this controller exists.
*/
- struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data;
- struct pci_resource **aprh, **tprh;
-
- if (id == ACPI_RSTYPE_ADDRESS16)
- dbg("acpi_pciehprm:16-Bit Address Space Resource\n");
- else
- dbg("acpi_pciehprm:32-Bit Address Space Resource\n");
-
- switch (data32->resource_type) {
- case ACPI_MEMORY_RANGE:
- dbg(" Resource Type: Memory Range\n");
- aprh = &ab->mem_head;
- tprh = &ab->tmem_head;
-
- switch (data32->attribute.memory.cache_attribute) {
- case ACPI_NON_CACHEABLE_MEMORY:
- dbg(" Type Specific: Noncacheable memory\n");
- break;
- case ACPI_CACHABLE_MEMORY:
- dbg(" Type Specific: Cacheable memory\n");
- break;
- case ACPI_WRITE_COMBINING_MEMORY:
- dbg(" Type Specific: Write-combining memory\n");
- break;
- case ACPI_PREFETCHABLE_MEMORY:
- aprh = &ab->p_mem_head;
- dbg(" Type Specific: Prefetchable memory\n");
- break;
- default:
- dbg(" Type Specific: Invalid cache attribute\n");
+ while (!handle) {
+ /*
+ * This hotplug controller was not listed in the ACPI name
+ * space at all. Try to get acpi handle of parent pci bus.
+ */
+ if (!pdev || !pdev->bus->parent)
break;
- }
-
- dbg(" Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only");
- break;
-
- case ACPI_IO_RANGE:
- dbg(" Resource Type: I/O Range\n");
- aprh = &ab->io_head;
- tprh = &ab->tio_head;
-
- switch (data32->attribute.io.range_attribute) {
- case ACPI_NON_ISA_ONLY_RANGES:
- dbg(" Type Specific: Non-ISA Io Addresses\n");
- break;
- case ACPI_ISA_ONLY_RANGES:
- dbg(" Type Specific: ISA Io Addresses\n");
- break;
- case ACPI_ENTIRE_RANGE:
- dbg(" Type Specific: ISA and non-ISA Io Addresses\n");
- break;
- default:
- dbg(" Type Specific: Invalid range attribute\n");
+ dbg("Could not find %s in acpi namespace, trying parent\n",
+ pci_name(pdev));
+ if (!pdev->bus->parent->self)
+ /* Parent must be a host bridge */
+ handle = acpi_get_pci_rootbridge_handle(
+ pci_domain_nr(pdev->bus->parent),
+ pdev->bus->parent->number);
+ else
+ handle = DEVICE_ACPI_HANDLE(
+ &(pdev->bus->parent->self->dev));
+ pdev = pdev->bus->parent->self;
+ }
+
+ while (handle) {
+ path_name = acpi_path_name(handle);
+ dbg("Trying to get hotplug control for %s \n", path_name);
+ status = pci_osc_control_set(handle,
+ OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
+ if (status == AE_NOT_FOUND)
+ status = acpi_run_oshp(handle);
+ if (ACPI_SUCCESS(status)) {
+ dbg("Gained control for hotplug HW for pci %s (%s)\n",
+ pci_name(dev), path_name);
+ return 0;
+ }
+ if (is_root_bridge(handle))
break;
- }
- break;
-
- case ACPI_BUS_NUMBER_RANGE:
- dbg(" Resource Type: Bus Number Range(fixed)\n");
- /* fixup to be compatible with the rest of php driver */
- data32->min_address_range++;
- data32->address_length--;
- aprh = &ab->bus_head;
- tprh = &ab->tbus_head;
- break;
- default:
- dbg(" Resource Type: Invalid resource type. Exiting.\n");
- return;
- }
-
- dbg(" Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer");
- dbg(" %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive");
- dbg(" Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not");
- dbg(" Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not");
- dbg(" Granularity: %08X\n", data32->granularity);
- dbg(" Address range min: %08X\n", data32->min_address_range);
- dbg(" Address range max: %08X\n", data32->max_address_range);
- dbg(" Address translation offset: %08X\n", data32->address_translation_offset);
- dbg(" Address Length: %08X\n", data32->address_length);
-
- if (0xFF != data32->resource_source.index) {
- dbg(" Resource Source Index: %X\n", data32->resource_source.index);
- /* dbg(" Resource Source: %s\n", data32->resource_source.string_ptr); */
- }
-
- pciehprm_add_resource(aprh, data32->min_address_range, data32->address_length);
-}
-
-static acpi_status acpi_parse_crs(
- struct acpi_bridge *ab,
- struct acpi_resource *crsbuf
- )
-{
- acpi_status status = AE_OK;
- struct acpi_resource *resource = crsbuf;
- u8 count = 0;
- u8 done = 0;
-
- while (!done) {
- dbg("acpi_pciehprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++);
- switch (resource->id) {
- case ACPI_RSTYPE_IRQ:
- dbg("Irq -------- Resource\n");
- break;
- case ACPI_RSTYPE_DMA:
- dbg("DMA -------- Resource\n");
- break;
- case ACPI_RSTYPE_START_DPF:
- dbg("Start DPF -------- Resource\n");
- break;
- case ACPI_RSTYPE_END_DPF:
- dbg("End DPF -------- Resource\n");
- break;
- case ACPI_RSTYPE_IO:
- acpi_parse_io (ab, &resource->data);
- break;
- case ACPI_RSTYPE_FIXED_IO:
- acpi_parse_fixed_io (ab, &resource->data);
- break;
- case ACPI_RSTYPE_VENDOR:
- dbg("Vendor -------- Resource\n");
- break;
- case ACPI_RSTYPE_END_TAG:
- dbg("End_tag -------- Resource\n");
- done = 1;
- break;
- case ACPI_RSTYPE_MEM24:
- dbg("Mem24 -------- Resource\n");
- break;
- case ACPI_RSTYPE_MEM32:
- dbg("Mem32 -------- Resource\n");
- break;
- case ACPI_RSTYPE_FIXED_MEM32:
- dbg("Fixed Mem32 -------- Resource\n");
- break;
- case ACPI_RSTYPE_ADDRESS16:
- acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16);
- break;
- case ACPI_RSTYPE_ADDRESS32:
- acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32);
- break;
- case ACPI_RSTYPE_ADDRESS64:
- info("Address64 -------- Resource unparsed\n");
- break;
- case ACPI_RSTYPE_EXT_IRQ:
- dbg("Ext Irq -------- Resource\n");
- break;
- default:
- dbg("Invalid -------- resource type 0x%x\n", resource->id);
- break;
- }
-
- resource = (struct acpi_resource *) ((char *)resource + resource->length);
- }
-
- return status;
-}
-
-static acpi_status acpi_get_crs( struct acpi_bridge *ab)
-{
- acpi_status status;
- struct acpi_resource *crsbuf;
-
- status = acpi_evaluate_crs(ab->handle, &crsbuf);
- if (ACPI_SUCCESS(status)) {
- status = acpi_parse_crs(ab, crsbuf);
- kfree(crsbuf);
-
- pciehp_resource_sort_and_combine(&ab->bus_head);
- pciehp_resource_sort_and_combine(&ab->io_head);
- pciehp_resource_sort_and_combine(&ab->mem_head);
- pciehp_resource_sort_and_combine(&ab->p_mem_head);
-
- pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
- pciehprm_add_resources (&ab->tio_head, ab->io_head);
- pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
- pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
- }
-
- return status;
-}
-
-/* find acpi_bridge downword from ab. */
-static struct acpi_bridge *
-find_acpi_bridge_by_bus(
- struct acpi_bridge *ab,
- int seg,
- int bus /* pdev->subordinate->number */
- )
-{
- struct acpi_bridge *lab = NULL;
-
- if (!ab)
- return NULL;
-
- if ((ab->bus == bus) && (ab->seg == seg))
- return ab;
-
- if (ab->child)
- lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
-
- if (!lab)
- if (ab->next)
- lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
-
- return lab;
-}
-
-/*
- * Build a device tree of ACPI PCI Bridges
- */
-static void pciehprm_acpi_register_a_bridge (
- struct acpi_bridge **head,
- struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
- struct acpi_bridge *cab /* child bridge to add */
- )
-{
- struct acpi_bridge *lpab;
- struct acpi_bridge *lcab;
-
- lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
- if (!lpab) {
- if (!(pab->type & BRIDGE_TYPE_HOST))
- warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
- pab->next = *head;
- *head = pab;
- lpab = pab;
- }
-
- if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
- return;
-
- lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
- if (lcab) {
- if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
- err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
- return;
- } else
- lcab = cab;
-
- lcab->parent = lpab;
- lcab->next = lpab->child;
- lpab->child = lcab;
-}
-
-static acpi_status pciehprm_acpi_build_php_slots_callback(
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval
- )
-{
- ulong bus_num;
- ulong seg_num;
- ulong sun, adr;
- ulong padr = 0;
- acpi_handle phandle = NULL;
- struct acpi_bridge *pab = (struct acpi_bridge *)context;
- struct acpi_bridge *lab;
- acpi_status status;
- u8 *path_name = acpi_path_name(handle);
-
- /* get _SUN */
- status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
- switch(status) {
- case AE_NOT_FOUND:
- return AE_OK;
- default:
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s _SUN fail=0x%x\n", path_name, status);
- return status;
- }
- }
-
- /* get _ADR. _ADR must exist if _SUN exists */
- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
- return status;
- }
-
- dbg("acpi_pciehprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
-
- status = acpi_get_parent(handle, &phandle);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s get_parent fail=0x%x\n", path_name, status);
- return (status);
- }
-
- bus_num = pab->bus;
- seg_num = pab->seg;
-
- if (pab->bus == bus_num) {
- lab = pab;
- } else {
- dbg("WARN: pab is not parent\n");
- lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
- if (!lab) {
- dbg("acpi_pciehprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
- lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
- if (!lab) {
- err("acpi_pciehprm: alloc for ab fail\n");
- return AE_NO_MEMORY;
- }
- memset(lab, 0, sizeof(struct acpi_bridge));
-
- lab->handle = phandle;
- lab->pbus = pab->bus;
- lab->pdevice = (int)(padr >> 16) & 0xffff;
- lab->pfunction = (int)(padr & 0xffff);
- lab->bus = (int)bus_num;
- lab->scanned = 0;
- lab->type = BRIDGE_TYPE_P2P;
-
- pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
- } else
- dbg("acpi_pciehprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
- }
-
- acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
-
- return (status);
-}
-
-static int pciehprm_acpi_build_php_slots(
- struct acpi_bridge *ab,
- u32 depth
- )
-{
- acpi_status status;
- u8 *path_name = acpi_path_name(ab->handle);
-
- /* Walk down this pci bridge to get _SUNs if any behind P2P */
- status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
- ab->handle,
- depth,
- pciehprm_acpi_build_php_slots_callback,
- ab,
- NULL );
- if (ACPI_FAILURE(status)) {
- dbg("acpi_pciehprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
- return -1;
- }
-
- return 0;
-}
-
-static void build_a_bridge(
- struct acpi_bridge *pab,
- struct acpi_bridge *ab
- )
-{
- u8 *path_name = acpi_path_name(ab->handle);
-
- pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
-
- switch (ab->type) {
- case BRIDGE_TYPE_HOST:
- dbg("acpi_pciehprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
- ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
- break;
- case BRIDGE_TYPE_P2P:
- dbg("acpi_pciehprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
- ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
- break;
- };
-
- /* build any immediate PHP slots under this pci bridge */
- pciehprm_acpi_build_php_slots(ab, 1);
-}
-
-static struct acpi_bridge * add_p2p_bridge(
- acpi_handle handle,
- struct acpi_bridge *pab, /* parent */
- ulong adr
- )
-{
- struct acpi_bridge *ab;
- struct pci_dev *pdev;
- ulong devnum, funcnum;
- u8 *path_name = acpi_path_name(handle);
-
- ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
- if (!ab) {
- err("acpi_pciehprm: alloc for ab fail\n");
- return NULL;
- }
- memset(ab, 0, sizeof(struct acpi_bridge));
-
- devnum = (adr >> 16) & 0xffff;
- funcnum = adr & 0xffff;
-
- pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
- if (!pdev || !pdev->subordinate) {
- err("acpi_pciehprm:%s is not a P2P Bridge\n", path_name);
- kfree(ab);
- return NULL;
- }
-
- ab->handle = handle;
- ab->seg = pab->seg;
- ab->pbus = pab->bus; /* or pdev->bus->number */
- ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
- ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
- ab->bus = pdev->subordinate->number;
- ab->scanned = 0;
- ab->type = BRIDGE_TYPE_P2P;
-
- dbg("acpi_pciehprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
- pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
- pab->bus, (u32)devnum, (u32)funcnum, path_name);
-
- build_a_bridge(pab, ab);
-
- return ab;
-}
-
-static acpi_status scan_p2p_bridge(
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval
- )
-{
- struct acpi_bridge *pab = (struct acpi_bridge *)context;
- struct acpi_bridge *ab;
- acpi_status status;
- ulong adr = 0;
- u8 *path_name = acpi_path_name(handle);
- ulong devnum, funcnum;
- struct pci_dev *pdev;
-
- /* get device, function */
- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
- if (ACPI_FAILURE(status)) {
- if (status != AE_NOT_FOUND)
- err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
- return AE_OK;
- }
-
- devnum = (adr >> 16) & 0xffff;
- funcnum = adr & 0xffff;
-
- pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
- if (!pdev)
- return AE_OK;
- if (!pdev->subordinate)
- return AE_OK;
-
- ab = add_p2p_bridge(handle, pab, adr);
- if (ab) {
- status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
- handle,
- (u32)1,
- scan_p2p_bridge,
- ab,
- NULL);
+ chandle = handle;
+ status = acpi_get_parent(chandle, &handle);
if (ACPI_FAILURE(status))
- dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
- }
-
- return AE_OK;
-}
-
-static struct acpi_bridge * add_host_bridge(
- acpi_handle handle,
- ulong segnum,
- ulong busnum
- )
-{
- ulong adr = 0;
- acpi_status status;
- struct acpi_bridge *ab;
- u8 *path_name = acpi_path_name(handle);
-
- /* get device, function: host br adr is always 0000 though. */
- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
- return NULL;
- }
- dbg("acpi_pciehprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum,
- (u32)busnum, (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
-
- ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
- if (!ab) {
- err("acpi_pciehprm: alloc for ab fail\n");
- return NULL;
- }
- memset(ab, 0, sizeof(struct acpi_bridge));
-
- ab->handle = handle;
- ab->seg = (int)segnum;
- ab->bus = ab->pbus = (int)busnum;
- ab->pdevice = (int)(adr >> 16) & 0xffff;
- ab->pfunction = (int)(adr & 0xffff);
- ab->scanned = 0;
- ab->type = BRIDGE_TYPE_HOST;
-
- /* get root pci bridge's current resources */
- status = acpi_get_crs(ab);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s evaluate _CRS fail=0x%x\n", path_name, status);
- kfree(ab);
- return NULL;
- }
-
- status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
- if (ACPI_FAILURE(status)) {
- err("%s: status %x\n", __FUNCTION__, status);
- osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED;
- } else {
- osc_run_status = NC_RUN_SUCCESS;
- }
- dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status);
-
- build_a_bridge(ab, ab);
-
- return ab;
-}
-
-static acpi_status acpi_scan_from_root_pci_callback (
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval
- )
-{
- ulong segnum = 0;
- ulong busnum = 0;
- acpi_status status;
- struct acpi_bridge *ab;
- u8 *path_name = acpi_path_name(handle);
-
- /* get bus number of this pci root bridge */
- status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
- if (ACPI_FAILURE(status)) {
- if (status != AE_NOT_FOUND) {
- err("acpi_pciehprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
- return status;
- }
- segnum = 0;
- }
-
- /* get bus number of this pci root bridge */
- status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
- return (status);
- }
-
- ab = add_host_bridge(handle, segnum, busnum);
- if (ab) {
- status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
- handle,
- 1,
- scan_p2p_bridge,
- ab,
- NULL);
- if (ACPI_FAILURE(status))
- dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
+ break;
}
- return AE_OK;
+ err("Cannot get control of hotplug hardware for pci %s\n",
+ pci_name(dev));
+ return -1;
}
-static int pciehprm_acpi_scan_pci (void)
+void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
+ struct hotplug_params *hpp)
{
- acpi_status status;
+ acpi_status status = AE_NOT_FOUND;
+ struct pci_dev *pdev = dev;
/*
- * TBD: traverse LDM device tree with the help of
- * unified ACPI augmented for php device population.
+ * _HPP settings apply to all child buses, until another _HPP is
+ * encountered. If we don't find an _HPP for the input pci dev,
+ * look for it in the parent device scope since that would apply to
+ * this pci dev. If we don't find any _HPP, use hardcoded defaults
*/
- status = acpi_get_devices ( PCI_ROOT_HID_STRING,
- acpi_scan_from_root_pci_callback,
- NULL,
- NULL );
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:get_device PCI ROOT HID fail=0x%x\n", status);
- return -1;
- }
-
- return 0;
-}
-
-int pciehprm_init(enum php_ctlr_type ctlr_type)
-{
- int rc;
-
- if (ctlr_type != PCI)
- return -ENODEV;
-
- dbg("pciehprm ACPI init <enter>\n");
- acpi_bridges_head = NULL;
-
- /* construct PCI bus:device tree of acpi_handles */
- rc = pciehprm_acpi_scan_pci();
- if (rc)
- return rc;
-
- if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) {
- err("Fails to gain control of native hot-plug\n");
- rc = -ENODEV;
- }
-
- dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success");
- return rc;
-}
-
-static void free_a_slot(struct acpi_php_slot *aps)
-{
- dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
-
- free_pci_resource (aps->io_head);
- free_pci_resource (aps->bus_head);
- free_pci_resource (aps->mem_head);
- free_pci_resource (aps->p_mem_head);
-
- kfree(aps);
-}
-
-static void free_a_bridge( struct acpi_bridge *ab)
-{
- struct acpi_php_slot *aps, *next;
-
- switch (ab->type) {
- case BRIDGE_TYPE_HOST:
- dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
- ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
- break;
- case BRIDGE_TYPE_P2P:
- dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
- ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
- break;
- };
-
- /* free slots first */
- for (aps = ab->slots; aps; aps = next) {
- next = aps->next;
- free_a_slot(aps);
- }
-
- free_pci_resource (ab->io_head);
- free_pci_resource (ab->tio_head);
- free_pci_resource (ab->bus_head);
- free_pci_resource (ab->tbus_head);
- free_pci_resource (ab->mem_head);
- free_pci_resource (ab->tmem_head);
- free_pci_resource (ab->p_mem_head);
- free_pci_resource (ab->tp_mem_head);
-
- kfree(ab);
-}
-
-static void pciehprm_free_bridges ( struct acpi_bridge *ab)
-{
- if (!ab)
- return;
-
- if (ab->child)
- pciehprm_free_bridges (ab->child);
-
- if (ab->next)
- pciehprm_free_bridges (ab->next);
-
- free_a_bridge(ab);
-}
-
-void pciehprm_cleanup(void)
-{
- pciehprm_free_bridges (acpi_bridges_head);
-}
-
-static int get_number_of_slots (
- struct acpi_bridge *ab,
- int selfonly
- )
-{
- struct acpi_php_slot *aps;
- int prev_slot = -1;
- int slot_num = 0;
-
- for ( aps = ab->slots; aps; aps = aps->next)
- if (aps->dev != prev_slot) {
- prev_slot = aps->dev;
- slot_num++;
- }
-
- if (ab->child)
- slot_num += get_number_of_slots (ab->child, 0);
-
- if (selfonly)
- return slot_num;
-
- if (ab->next)
- slot_num += get_number_of_slots (ab->next, 0);
-
- return slot_num;
-}
-
-static int print_acpi_resources (struct acpi_bridge *ab)
-{
- struct acpi_php_slot *aps;
- int i;
-
- switch (ab->type) {
- case BRIDGE_TYPE_HOST:
- dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle));
- break;
- case BRIDGE_TYPE_P2P:
- dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle));
- break;
- };
-
- print_pci_resources (ab);
-
- for ( i = -1, aps = ab->slots; aps; aps = aps->next) {
- if (aps->dev == i)
- continue;
- dbg(" Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
- print_slot_resources(aps);
- i = aps->dev;
- }
-
- if (ab->child)
- print_acpi_resources (ab->child);
-
- if (ab->next)
- print_acpi_resources (ab->next);
-
- return 0;
-}
-
-int pciehprm_print_pirt(void)
-{
- dbg("PCIEHPRM ACPI Slots\n");
- if (acpi_bridges_head)
- print_acpi_resources (acpi_bridges_head);
-
- return 0;
-}
-
-static struct acpi_php_slot * get_acpi_slot (
- struct acpi_bridge *ab,
- u32 sun
- )
-{
- struct acpi_php_slot *aps = NULL;
-
- for ( aps = ab->slots; aps; aps = aps->next)
- if (aps->sun == sun)
- return aps;
-
- if (!aps && ab->child) {
- aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
- if (aps)
- return aps;
- }
-
- if (!aps && ab->next) {
- aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
- if (aps)
- return aps;
- }
-
- return aps;
-
-}
-
-#if 0
-void * pciehprm_get_slot(struct slot *slot)
-{
- struct acpi_bridge *ab = acpi_bridges_head;
- struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
-
- aps->slot = slot;
-
- dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
-
- return (void *)aps;
-}
-#endif
-
-static void pciehprm_dump_func_res( struct pci_func *fun)
-{
- struct pci_func *func = fun;
-
- if (func->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (func->bus_head);
- }
- if (func->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (func->io_head);
- }
- if (func->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (func->mem_head);
- }
- if (func->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (func->p_mem_head);
- }
-}
-
-static void pciehprm_dump_ctrl_res( struct controller *ctlr)
-{
- struct controller *ctrl = ctlr;
-
- if (ctrl->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (ctrl->bus_head);
- }
- if (ctrl->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (ctrl->io_head);
- }
- if (ctrl->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (ctrl->mem_head);
- }
- if (ctrl->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (ctrl->p_mem_head);
- }
-}
-
-static int pciehprm_get_used_resources (
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
-}
-
-static int configure_existing_function(
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- int rc;
-
- /* see how much resources the func has used. */
- rc = pciehprm_get_used_resources (ctrl, func);
-
- if (!rc) {
- /* subtract the resources used by the func from ctrl resources */
- rc = pciehprm_delete_resources (&ctrl->bus_head, func->bus_head);
- rc |= pciehprm_delete_resources (&ctrl->io_head, func->io_head);
- rc |= pciehprm_delete_resources (&ctrl->mem_head, func->mem_head);
- rc |= pciehprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
- if (rc)
- warn("aCEF: cannot del used resources\n");
- } else
- err("aCEF: cannot get used resources\n");
-
- return rc;
-}
-
-static int bind_pci_resources_to_slots ( struct controller *ctrl)
-{
- struct pci_func *func, new_func;
- int busn = ctrl->slot_bus;
- int devn, funn;
- u32 vid;
-
- for (devn = 0; devn < 32; devn++) {
- for (funn = 0; funn < 8; funn++) {
- /*
- if (devn == ctrl->device && funn == ctrl->function)
- continue;
- */
- /* find out if this entry is for an occupied slot */
- vid = 0xFFFFFFFF;
- pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
-
- if (vid != 0xFFFFFFFF) {
- dbg("%s: vid = %x\n", __FUNCTION__, vid);
- func = pciehp_slot_find(busn, devn, funn);
- if (!func) {
- memset(&new_func, 0, sizeof(struct pci_func));
- new_func.bus = busn;
- new_func.device = devn;
- new_func.function = funn;
- new_func.is_a_board = 1;
- configure_existing_function(ctrl, &new_func);
- pciehprm_dump_func_res(&new_func);
- } else {
- configure_existing_function(ctrl, func);
- pciehprm_dump_func_res(func);
- }
- dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
- }
- }
- }
-
- return 0;
-}
-
-static int bind_pci_resources(
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int status = 0;
-
- if (ab->bus_head) {
- dbg("bapr: BUS Resources add on PCI 0x%x\n", ab->bus);
- status = pciehprm_add_resources (&ctrl->bus_head, ab->bus_head);
- if (pciehprm_delete_resources (&ab->bus_head, ctrl->bus_head))
- warn("bapr: cannot sub BUS Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No BUS Resource on PCI 0x%x.\n", ab->bus);
-
- if (ab->io_head) {
- dbg("bapr: IO Resources add on PCI 0x%x\n", ab->bus);
- status = pciehprm_add_resources (&ctrl->io_head, ab->io_head);
- if (pciehprm_delete_resources (&ab->io_head, ctrl->io_head))
- warn("bapr: cannot sub IO Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No IO Resource on PCI 0x%x.\n", ab->bus);
-
- if (ab->mem_head) {
- dbg("bapr: MEM Resources add on PCI 0x%x\n", ab->bus);
- status = pciehprm_add_resources (&ctrl->mem_head, ab->mem_head);
- if (pciehprm_delete_resources (&ab->mem_head, ctrl->mem_head))
- warn("bapr: cannot sub MEM Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No MEM Resource on PCI 0x%x.\n", ab->bus);
-
- if (ab->p_mem_head) {
- dbg("bapr: PMEM Resources add on PCI 0x%x\n", ab->bus);
- status = pciehprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head);
- if (pciehprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head))
- warn("bapr: cannot sub PMEM Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No PMEM Resource on PCI 0x%x.\n", ab->bus);
-
- return status;
-}
-
-static int no_pci_resources( struct acpi_bridge *ab)
-{
- return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head);
-}
-
-static int find_pci_bridge_resources (
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int rc = 0;
- struct pci_func func;
-
- memset(&func, 0, sizeof(struct pci_func));
-
- func.bus = ab->pbus;
- func.device = ab->pdevice;
- func.function = ab->pfunction;
- func.is_a_board = 1;
-
- /* Get used resources for this PCI bridge */
- rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
-
- ab->io_head = func.io_head;
- ab->mem_head = func.mem_head;
- ab->p_mem_head = func.p_mem_head;
- ab->bus_head = func.bus_head;
- if (ab->bus_head)
- pciehprm_delete_resource(&ab->bus_head, ctrl->pci_dev->subordinate->number, 1);
-
- return rc;
-}
-
-static int get_pci_resources_from_bridge(
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int rc = 0;
-
- dbg("grfb: Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus);
-
- rc = find_pci_bridge_resources (ctrl, ab);
-
- pciehp_resource_sort_and_combine(&ab->bus_head);
- pciehp_resource_sort_and_combine(&ab->io_head);
- pciehp_resource_sort_and_combine(&ab->mem_head);
- pciehp_resource_sort_and_combine(&ab->p_mem_head);
-
- pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
- pciehprm_add_resources (&ab->tio_head, ab->io_head);
- pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
- pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
-
- return rc;
-}
-
-static int get_pci_resources(
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int rc = 0;
-
- if (no_pci_resources(ab)) {
- dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus);
- rc = get_pci_resources_from_bridge(ctrl, ab);
- }
-
- return rc;
-}
-
-/*
- * Get resources for this ctrl.
- * 1. get total resources from ACPI _CRS or bridge (this ctrl)
- * 2. find used resources of existing adapters
- * 3. subtract used resources from total resources
- */
-int pciehprm_find_available_resources( struct controller *ctrl)
-{
- int rc = 0;
- struct acpi_bridge *ab;
-
- ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number);
- if (!ab) {
- err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
- return -1;
- }
- if (no_pci_resources(ab)) {
- rc = get_pci_resources(ctrl, ab);
- if (rc) {
- err("pfar:cannot get pci resources of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
- return -1;
- }
- }
-
- rc = bind_pci_resources(ctrl, ab);
- dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
- pciehprm_dump_ctrl_res(ctrl);
-
- bind_pci_resources_to_slots (ctrl);
-
- dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
- pciehprm_dump_ctrl_res(ctrl);
-
- return rc;
-}
-
-int pciehprm_set_hpp(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type
- )
-{
- struct acpi_bridge *ab;
- struct pci_bus lpci_bus, *pci_bus;
- int rc = 0;
- unsigned int devfn;
- u8 cls= 0x08; /* default cache line size */
- u8 lt = 0x40; /* default latency timer */
- u8 ep = 0;
- u8 es = 0;
-
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
-
- if (ab) {
- if (ab->_hpp) {
- lt = (u8)ab->_hpp->latency_timer;
- cls = (u8)ab->_hpp->cache_line_size;
- ep = (u8)ab->_hpp->enable_perr;
- es = (u8)ab->_hpp->enable_serr;
- } else
- dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
- } else
- dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
-
-
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- /* set subordinate Latency Timer */
- rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
+ while (pdev && (ACPI_FAILURE(status))) {
+ acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
+ if (!handle)
+ break;
+ status = acpi_run_hpp(handle, hpp);
+ if (!(pdev->bus->parent))
+ break;
+ /* Check if a parent object supports _HPP */
+ pdev = pdev->bus->parent->self;
}
-
- /* set base Latency Timer */
- rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
- dbg(" set latency timer =0x%02x: %x\n", lt, rc);
-
- rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
- dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
-
- return rc;
}
-void pciehprm_enable_card(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type)
-{
- u16 command, cmd, bcommand, bcmd;
- struct pci_bus lpci_bus, *pci_bus;
- struct acpi_bridge *ab;
- unsigned int devfn;
- int rc;
-
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &cmd);
-
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcmd);
- }
-
- command = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
- | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
- bcommand = bcmd | PCI_BRIDGE_CTL_NO_ISA;
-
- ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
- if (ab) {
- if (ab->_hpp) {
- if (ab->_hpp->enable_perr) {
- command |= PCI_COMMAND_PARITY;
- bcommand |= PCI_BRIDGE_CTL_PARITY;
- } else {
- command &= ~PCI_COMMAND_PARITY;
- bcommand &= ~PCI_BRIDGE_CTL_PARITY;
- }
- if (ab->_hpp->enable_serr) {
- command |= PCI_COMMAND_SERR;
- bcommand |= PCI_BRIDGE_CTL_SERR;
- } else {
- command &= ~PCI_COMMAND_SERR;
- bcommand &= ~PCI_BRIDGE_CTL_SERR;
- }
- } else
- dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
- } else
- dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
-
- if (command != cmd) {
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
- }
- if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
- }
-}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
index 76c727c..29180df 100644
--- a/drivers/pci/hotplug/pciehprm_nonacpi.c
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.c
@@ -27,479 +27,21 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/pci.h>
-#include <linux/init.h>
#include <linux/slab.h>
-
-#include <asm/uaccess.h>
-#ifdef CONFIG_IA64
-#include <asm/iosapic.h>
-#endif
-
#include "pciehp.h"
-#include "pciehprm.h"
-#include "pciehprm_nonacpi.h"
-
-void pciehprm_cleanup(void)
+void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
+ struct hotplug_params *hpp)
{
return;
}
-int pciehprm_print_pirt(void)
-{
- return 0;
-}
-
-int pciehprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
-{
-
- *sun = (u8) (ctrl->first_slot);
- return 0;
-}
-
-
-static void print_pci_resource ( struct pci_resource *aprh)
-{
- struct pci_resource *res;
-
- for (res = aprh; res; res = res->next)
- dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
-}
-
-
-static void phprm_dump_func_res( struct pci_func *fun)
-{
- struct pci_func *func = fun;
-
- if (func->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (func->bus_head);
- }
- if (func->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (func->io_head);
- }
- if (func->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (func->mem_head);
- }
- if (func->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (func->p_mem_head);
- }
-}
-
-static int phprm_get_used_resources (
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
-}
-
-static int phprm_delete_resource(
- struct pci_resource **aprh,
- ulong base,
- ulong size)
-{
- struct pci_resource *res;
- struct pci_resource *prevnode;
- struct pci_resource *split_node;
- ulong tbase;
-
- pciehp_resource_sort_and_combine(aprh);
-
- for (res = *aprh; res; res = res->next) {
- if (res->base > base)
- continue;
-
- if ((res->base + res->length) < (base + size))
- continue;
-
- if (res->base < base) {
- tbase = base;
-
- if ((res->length - (tbase - res->base)) < size)
- continue;
-
- split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base;
- split_node->length = tbase - res->base;
- res->base = tbase;
- res->length -= split_node->length;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (res->length >= size) {
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base + size;
- split_node->length = res->length - size;
- res->length = size;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (*aprh == res) {
- *aprh = res->next;
- } else {
- prevnode = *aprh;
- while (prevnode->next != res)
- prevnode = prevnode->next;
-
- prevnode->next = res->next;
- }
- res->next = NULL;
- kfree(res);
- break;
- }
-
- return 0;
-}
-
-
-static int phprm_delete_resources(
- struct pci_resource **aprh,
- struct pci_resource *this
- )
-{
- struct pci_resource *res;
-
- for (res = this; res; res = res->next)
- phprm_delete_resource(aprh, res->base, res->length);
-
- return 0;
-}
-
-
-static int configure_existing_function(
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- int rc;
-
- /* see how much resources the func has used. */
- rc = phprm_get_used_resources (ctrl, func);
-
- if (!rc) {
- /* subtract the resources used by the func from ctrl resources */
- rc = phprm_delete_resources (&ctrl->bus_head, func->bus_head);
- rc |= phprm_delete_resources (&ctrl->io_head, func->io_head);
- rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head);
- rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
- if (rc)
- warn("aCEF: cannot del used resources\n");
- } else
- err("aCEF: cannot get used resources\n");
-
- return rc;
-}
-
-static int pciehprm_delete_resource(
- struct pci_resource **aprh,
- ulong base,
- ulong size)
-{
- struct pci_resource *res;
- struct pci_resource *prevnode;
- struct pci_resource *split_node;
- ulong tbase;
-
- pciehp_resource_sort_and_combine(aprh);
-
- for (res = *aprh; res; res = res->next) {
- if (res->base > base)
- continue;
-
- if ((res->base + res->length) < (base + size))
- continue;
-
- if (res->base < base) {
- tbase = base;
-
- if ((res->length - (tbase - res->base)) < size)
- continue;
-
- split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base;
- split_node->length = tbase - res->base;
- res->base = tbase;
- res->length -= split_node->length;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (res->length >= size) {
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base + size;
- split_node->length = res->length - size;
- res->length = size;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (*aprh == res) {
- *aprh = res->next;
- } else {
- prevnode = *aprh;
- while (prevnode->next != res)
- prevnode = prevnode->next;
-
- prevnode->next = res->next;
- }
- res->next = NULL;
- kfree(res);
- break;
- }
-
- return 0;
-}
-
-static int bind_pci_resources_to_slots ( struct controller *ctrl)
+int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
- struct pci_func *func, new_func;
- int busn = ctrl->slot_bus;
- int devn, funn;
- u32 vid;
-
- for (devn = 0; devn < 32; devn++) {
- for (funn = 0; funn < 8; funn++) {
- /*
- if (devn == ctrl->device && funn == ctrl->function)
- continue;
- */
- /* find out if this entry is for an occupied slot */
- vid = 0xFFFFFFFF;
-
- pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
-
- if (vid != 0xFFFFFFFF) {
- dbg("%s: vid = %x bus %x dev %x fun %x\n", __FUNCTION__,
- vid, busn, devn, funn);
- func = pciehp_slot_find(busn, devn, funn);
- dbg("%s: func = %p\n", __FUNCTION__,func);
- if (!func) {
- memset(&new_func, 0, sizeof(struct pci_func));
- new_func.bus = busn;
- new_func.device = devn;
- new_func.function = funn;
- new_func.is_a_board = 1;
- configure_existing_function(ctrl, &new_func);
- phprm_dump_func_res(&new_func);
- } else {
- configure_existing_function(ctrl, func);
- phprm_dump_func_res(func);
- }
- dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
- }
- }
- }
-
return 0;
}
-
-static void phprm_dump_ctrl_res( struct controller *ctlr)
-{
- struct controller *ctrl = ctlr;
-
- if (ctrl->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (ctrl->bus_head);
- }
- if (ctrl->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (ctrl->io_head);
- }
- if (ctrl->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (ctrl->mem_head);
- }
- if (ctrl->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (ctrl->p_mem_head);
- }
-}
-
-/*
- * phprm_find_available_resources
- *
- * Finds available memory, IO, and IRQ resources for programming
- * devices which may be added to the system
- * this function is for hot plug ADD!
- *
- * returns 0 if success
- */
-int pciehprm_find_available_resources(struct controller *ctrl)
-{
- struct pci_func func;
- u32 rc;
-
- memset(&func, 0, sizeof(struct pci_func));
-
- func.bus = ctrl->bus;
- func.device = ctrl->device;
- func.function = ctrl->function;
- func.is_a_board = 1;
-
- /* Get resources for this PCI bridge */
- rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
- dbg("%s: pciehp_save_used_resources rc = %d\n", __FUNCTION__, rc);
-
- if (func.mem_head)
- func.mem_head->next = ctrl->mem_head;
- ctrl->mem_head = func.mem_head;
-
- if (func.p_mem_head)
- func.p_mem_head->next = ctrl->p_mem_head;
- ctrl->p_mem_head = func.p_mem_head;
-
- if (func.io_head)
- func.io_head->next = ctrl->io_head;
- ctrl->io_head = func.io_head;
-
- if(func.bus_head)
- func.bus_head->next = ctrl->bus_head;
- ctrl->bus_head = func.bus_head;
-
- if (ctrl->bus_head)
- pciehprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1);
-
- dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
- phprm_dump_ctrl_res(ctrl);
-
- dbg("%s: before bind_pci_resources_to slots\n", __FUNCTION__);
-
- bind_pci_resources_to_slots (ctrl);
-
- dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
- phprm_dump_ctrl_res(ctrl);
-
- return (rc);
-}
-
-int pciehprm_set_hpp(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type)
-{
- u32 rc;
- u8 temp_byte;
- struct pci_bus lpci_bus, *pci_bus;
- unsigned int devfn;
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- temp_byte = 0x40; /* hard coded value for LT */
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- /* set subordinate Latency Timer */
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
-
- if (rc) {
- dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__,
- func->bus, func->device, func->function);
- return rc;
- }
- }
-
- /* set base Latency Timer */
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
-
- if (rc) {
- dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
- return rc;
- }
-
- /* set Cache Line size */
- temp_byte = 0x08; /* hard coded value for CLS */
-
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
-
- if (rc) {
- dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
- }
-
- /* set enable_perr */
- /* set enable_serr */
-
- return rc;
-}
-
-void pciehprm_enable_card(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type)
-{
- u16 command, bcommand;
- struct pci_bus lpci_bus, *pci_bus;
- unsigned int devfn;
- int rc;
-
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
-
- command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
- | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
- | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
-
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
-
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
-
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
-
- bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
- | PCI_BRIDGE_CTL_NO_ISA;
-
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
- }
-}
-
-static int legacy_pciehprm_init_pci(void)
-{
- return 0;
-}
-
-int pciehprm_init(enum php_ctlr_type ctrl_type)
-{
- int retval;
-
- switch (ctrl_type) {
- case PCI:
- retval = legacy_pciehprm_init_pci();
- break;
- default:
- retval = -ENODEV;
- break;
- }
-
- return retval;
-}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.h b/drivers/pci/hotplug/pciehprm_nonacpi.h
deleted file mode 100644
index b10603b..0000000
--- a/drivers/pci/hotplug/pciehprm_nonacpi.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * PCIEHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2003-2004 Intel Corporation
- *
- * All rights reserved.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT. 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.
- *
- * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
- *
- */
-
-#ifndef _PCIEHPRM_NONACPI_H_
-#define _PCIEHPRM_NONACPI_H_
-
-struct irq_info {
- u8 bus, devfn; /* bus, device and function */
- struct {
- u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
- u16 bitmap; /* Available IRQs */
- } __attribute__ ((packed)) irq[4];
- u8 slot; /* slot number, 0=onboard */
- u8 rfu;
-} __attribute__ ((packed));
-
-struct irq_routing_table {
- u32 signature; /* PIRQ_SIGNATURE should be here */
- u16 version; /* PIRQ_VERSION */
- u16 size; /* Table size in bytes */
- u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
- u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
- u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
- u32 miniport_data; /* Crap */
- u8 rfu[11];
- u8 checksum; /* Modulo 256 checksum must give zero */
- struct irq_info slots[0];
-} __attribute__ ((packed));
-
-#endif /* _PCIEHPRM_NONACPI_H_ */
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index e8593a6..cc03609 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -134,43 +134,6 @@ static void rpadlpar_claim_one_bus(struct pci_bus *b)
rpadlpar_claim_one_bus(child_bus);
}
-static int pci_add_secondary_bus(struct device_node *dn,
- struct pci_dev *bridge_dev)
-{
- struct pci_dn *pdn = dn->data;
- struct pci_controller *hose = pdn->phb;
- struct pci_bus *child;
- u8 sec_busno;
-
- /* Get busno of downstream bus */
- pci_read_config_byte(bridge_dev, PCI_SECONDARY_BUS, &sec_busno);
-
- /* Allocate and add to children of bridge_dev->bus */
- child = pci_add_new_bus(bridge_dev->bus, bridge_dev, sec_busno);
- if (!child) {
- printk(KERN_ERR "%s: could not add secondary bus\n", __FUNCTION__);
- return -ENOMEM;
- }
-
- sprintf(child->name, "PCI Bus #%02x", child->number);
-
- /* Fixup subordinate bridge bases and resources */
- pcibios_fixup_bus(child);
-
- /* Claim new bus resources */
- rpadlpar_claim_one_bus(bridge_dev->bus);
-
- if (hose->last_busno < child->number)
- hose->last_busno = child->number;
-
- pdn->bussubno = child->number;
-
- /* ioremap() for child bus, which may or may not succeed */
- remap_bus_range(child);
-
- return 0;
-}
-
static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
struct device_node *dev_dn)
{
@@ -188,29 +151,41 @@ static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
{
struct pci_dn *pdn = dn->data;
- struct pci_controller *hose = pdn->phb;
+ struct pci_controller *phb = pdn->phb;
struct pci_dev *dev = NULL;
- /* Scan phb bus for EADS device, adding new one to bus->devices */
- if (!pci_scan_single_device(hose->bus, pdn->devfn)) {
- printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__);
+ rpaphp_eeh_init_nodes(dn);
+ /* Add EADS device to PHB bus, adding new entry to bus->devices */
+ dev = of_create_pci_dev(dn, phb->bus, pdn->devfn);
+ if (!dev) {
+ printk(KERN_ERR "%s: failed to create pci dev for %s\n",
+ __FUNCTION__, dn->full_name);
return NULL;
}
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+ of_scan_pci_bridge(dn, dev);
+
+ rpaphp_init_new_devs(dev->subordinate);
+
+ /* Claim new bus resources */
+ rpadlpar_claim_one_bus(dev->bus);
+
+ /* ioremap() for child bus, which may or may not succeed */
+ (void) remap_bus_range(dev->bus);
+
/* Add new devices to global lists. Register in proc, sysfs. */
- pci_bus_add_devices(hose->bus);
+ pci_bus_add_devices(phb->bus);
/* Confirm new bridge dev was created */
- dev = dlpar_find_new_dev(hose->bus, dn);
+ dev = dlpar_find_new_dev(phb->bus, dn);
if (dev) {
if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
printk(KERN_ERR "%s: unexpected header type %d\n",
__FUNCTION__, dev->hdr_type);
return NULL;
}
-
- if (pci_add_secondary_bus(dn, dev))
- return NULL;
}
return dev;
@@ -219,7 +194,6 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
{
struct pci_dev *dev;
- int rc;
if (rpaphp_find_pci_bus(dn))
return -EINVAL;
@@ -232,15 +206,6 @@ static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
return -EIO;
}
- if (dn->child) {
- rc = rpaphp_config_pci_adapter(dev->subordinate);
- if (rc < 0) {
- printk(KERN_ERR "%s: unable to enable slot %s\n",
- __FUNCTION__, drc_name);
- return -EIO;
- }
- }
-
/* Add hotplug slot */
if (rpaphp_add_slot(dn)) {
printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
@@ -435,6 +400,8 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
__FUNCTION__, drc_name);
return -EIO;
}
+ } else {
+ rpaphp_unconfig_pci_adapter(bus);
}
if (unmap_bus_range(bus)) {
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 71ea5f9..57ea71a 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -93,6 +93,8 @@ extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
extern int rpaphp_enable_pci_slot(struct slot *slot);
extern int register_pci_slot(struct slot *slot);
extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
+extern void rpaphp_init_new_devs(struct pci_bus *bus);
+extern void rpaphp_eeh_init_nodes(struct device_node *dn);
extern int rpaphp_config_pci_adapter(struct pci_bus *bus);
extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus);
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index f7c12d7..4b35097 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -154,8 +154,7 @@ exit:
}
/* Must be called before pci_bus_add_devices */
-static void
-rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
+void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
{
struct pci_dev *dev;
@@ -184,6 +183,20 @@ rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
}
}
+static void rpaphp_eeh_add_bus_device(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ eeh_add_device_late(dev);
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ struct pci_bus *subbus = dev->subordinate;
+ if (subbus)
+ rpaphp_eeh_add_bus_device (subbus);
+ }
+ }
+}
+
static int rpaphp_pci_config_bridge(struct pci_dev *dev)
{
u8 sec_busno;
@@ -217,6 +230,13 @@ static int rpaphp_pci_config_bridge(struct pci_dev *dev)
return 0;
}
+void rpaphp_init_new_devs(struct pci_bus *bus)
+{
+ rpaphp_fixup_new_pci_devices(bus, 0);
+ rpaphp_eeh_add_bus_device(bus);
+}
+EXPORT_SYMBOL_GPL(rpaphp_init_new_devs);
+
/*****************************************************************************
rpaphp_pci_config_slot() will configure all devices under the
given slot->dn and return the the first pci_dev.
@@ -233,36 +253,51 @@ rpaphp_pci_config_slot(struct pci_bus *bus)
if (!dn || !dn->child)
return NULL;
- slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
+ if (_machine == PLATFORM_PSERIES_LPAR) {
+ of_scan_bus(dn, bus);
+ if (list_empty(&bus->devices)) {
+ err("%s: No new device found\n", __FUNCTION__);
+ return NULL;
+ }
- /* pci_scan_slot should find all children */
- num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
- if (num) {
- rpaphp_fixup_new_pci_devices(bus, 1);
+ rpaphp_init_new_devs(bus);
pci_bus_add_devices(bus);
- }
- if (list_empty(&bus->devices)) {
- err("%s: No new device found\n", __FUNCTION__);
- return NULL;
- }
- list_for_each_entry(dev, &bus->devices, bus_list) {
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
- rpaphp_pci_config_bridge(dev);
+ dev = list_entry(&bus->devices, struct pci_dev, bus_list);
+ } else {
+ slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
+
+ /* pci_scan_slot should find all children */
+ num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+ if (num) {
+ rpaphp_fixup_new_pci_devices(bus, 1);
+ pci_bus_add_devices(bus);
+ }
+ if (list_empty(&bus->devices)) {
+ err("%s: No new device found\n", __FUNCTION__);
+ return NULL;
+ }
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+ rpaphp_pci_config_bridge(dev);
+
+ rpaphp_eeh_add_bus_device(bus);
+ }
}
return dev;
}
-static void enable_eeh(struct device_node *dn)
+void rpaphp_eeh_init_nodes(struct device_node *dn)
{
struct device_node *sib;
for (sib = dn->child; sib; sib = sib->sibling)
- enable_eeh(sib);
+ rpaphp_eeh_init_nodes(sib);
eeh_add_device_early(dn);
return;
}
+EXPORT_SYMBOL_GPL(rpaphp_eeh_init_nodes);
static void print_slot_pci_funcs(struct pci_bus *bus)
{
@@ -289,7 +324,7 @@ int rpaphp_config_pci_adapter(struct pci_bus *bus)
if (!dn)
goto exit;
- enable_eeh(dn);
+ rpaphp_eeh_init_nodes(dn);
dev = rpaphp_pci_config_slot(bus);
if (!dev) {
err("%s: can't find any devices.\n", __FUNCTION__);
@@ -331,6 +366,7 @@ int rpaphp_unconfig_pci_adapter(struct pci_bus *bus)
}
return 0;
}
+EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter);
static int setup_pci_hotplug_slot_info(struct slot *slot)
{
@@ -444,8 +480,8 @@ int rpaphp_enable_pci_slot(struct slot *slot)
retval = rpaphp_config_pci_adapter(slot->bus);
if (!retval) {
slot->state = CONFIGURED;
- dbg("%s: PCI devices in slot[%s] has been configured\n",
- __FUNCTION__, slot->name);
+ info("%s: devices in slot[%s] configured\n",
+ __FUNCTION__, slot->name);
} else {
slot->state = NOT_CONFIGURED;
dbg("%s: no pci_dev struct for adapter in slot[%s]\n",
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 40905a6..9987a6f 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -31,6 +31,8 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/pci.h>
+#include <linux/interrupt.h>
+
#include "shpchp.h"
#ifdef DEBUG
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index b8e95ac..38009bc 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -34,7 +34,7 @@
#include "../pci.h"
#include "shpchp.h"
-void program_fw_provided_values(struct pci_dev *dev)
+static void program_fw_provided_values(struct pci_dev *dev)
{
u16 pci_cmd, pci_bctl;
struct pci_dev *cdev;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index a203355..202b750 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -23,6 +23,8 @@
#include "pci.h"
#include "msi.h"
+#define MSI_TARGET_CPU first_cpu(cpu_online_map)
+
static DEFINE_SPINLOCK(msi_lock);
static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
static kmem_cache_t* msi_cachep;
@@ -92,6 +94,7 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
struct msi_desc *entry;
struct msg_address address;
unsigned int irq = vector;
+ unsigned int dest_cpu = first_cpu(cpu_mask);
entry = (struct msi_desc *)msi_desc[vector];
if (!entry || !entry->dev)
@@ -108,9 +111,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
pci_read_config_dword(entry->dev, msi_lower_address_reg(pos),
&address.lo_address.value);
address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
- address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) <<
- MSI_TARGET_CPU_SHIFT);
- entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
+ address.lo_address.value |= (cpu_physical_id(dest_cpu) <<
+ MSI_TARGET_CPU_SHIFT);
+ entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu);
pci_write_config_dword(entry->dev, msi_lower_address_reg(pos),
address.lo_address.value);
set_native_irq_info(irq, cpu_mask);
@@ -123,9 +126,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
address.lo_address.value = readl(entry->mask_base + offset);
address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
- address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) <<
- MSI_TARGET_CPU_SHIFT);
- entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
+ address.lo_address.value |= (cpu_physical_id(dest_cpu) <<
+ MSI_TARGET_CPU_SHIFT);
+ entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu);
writel(address.lo_address.value, entry->mask_base + offset);
set_native_irq_info(irq, cpu_mask);
break;
@@ -259,14 +262,15 @@ static void msi_data_init(struct msg_data *msi_data,
static void msi_address_init(struct msg_address *msi_address)
{
unsigned int dest_id;
+ unsigned long dest_phys_id = cpu_physical_id(MSI_TARGET_CPU);
memset(msi_address, 0, sizeof(struct msg_address));
msi_address->hi_address = (u32)0;
dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT);
- msi_address->lo_address.u.dest_mode = MSI_DEST_MODE;
+ msi_address->lo_address.u.dest_mode = MSI_PHYSICAL_MODE;
msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE;
msi_address->lo_address.u.dest_id = dest_id;
- msi_address->lo_address.value |= (MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT);
+ msi_address->lo_address.value |= (dest_phys_id << MSI_TARGET_CPU_SHIFT);
}
static int msi_free_vector(struct pci_dev* dev, int vector, int reassign);
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index e9e37ab..a9b00cc 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -91,9 +91,7 @@ acpi_query_osc (
static acpi_status
acpi_run_osc (
acpi_handle handle,
- u32 level,
- void *context,
- void **retval )
+ void *context)
{
acpi_status status;
struct acpi_object_list input;
@@ -184,7 +182,7 @@ EXPORT_SYMBOL(pci_osc_support_set);
*
* Attempt to take control from Firmware on requested control bits.
**/
-acpi_status pci_osc_control_set(u32 flags)
+acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
{
acpi_status status;
u32 ctrlset;
@@ -198,10 +196,7 @@ acpi_status pci_osc_control_set(u32 flags)
return AE_SUPPORT;
}
ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
- status = acpi_get_devices ( PCI_ROOT_HID_STRING,
- acpi_run_osc,
- ctrlset_buf,
- NULL );
+ status = acpi_run_osc(handle, ctrlset_buf);
if (ACPI_FAILURE (status)) {
ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 94e68c5..a9046d4 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -37,7 +37,7 @@ struct pci_dynid {
* Adds a new dynamic pci device ID to this driver,
* and causes the driver to probe for all devices again.
*/
-static inline ssize_t
+static ssize_t
store_new_id(struct device_driver *driver, const char *buf, size_t count)
{
struct pci_dynid *dynid;
@@ -364,15 +364,16 @@ static struct kobj_type pci_driver_kobj_type = {
};
/**
- * pci_register_driver - register a new pci driver
+ * __pci_register_driver - register a new pci driver
* @drv: the driver structure to register
+ * @owner: owner module of drv
*
* Adds the driver structure to the list of registered drivers.
* Returns a negative value on error, otherwise 0.
* If no error occurred, the driver remains registered even if
* no device was claimed during registration.
*/
-int pci_register_driver(struct pci_driver *drv)
+int __pci_register_driver(struct pci_driver *drv, struct module *owner)
{
int error;
@@ -389,7 +390,7 @@ int pci_register_driver(struct pci_driver *drv)
printk(KERN_WARNING "Warning: PCI driver %s has a struct "
"device_driver shutdown method, please update!\n",
drv->name);
- drv->driver.owner = drv->owner;
+ drv->driver.owner = owner;
drv->driver.kobj.ktype = &pci_driver_kobj_type;
spin_lock_init(&drv->dynids.lock);
@@ -526,7 +527,7 @@ postcore_initcall(pci_driver_init);
EXPORT_SYMBOL(pci_match_id);
EXPORT_SYMBOL(pci_match_device);
-EXPORT_SYMBOL(pci_register_driver);
+EXPORT_SYMBOL(__pci_register_driver);
EXPORT_SYMBOL(pci_unregister_driver);
EXPORT_SYMBOL(pci_dev_driver);
EXPORT_SYMBOL(pci_bus_type);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e74d758..8e287a8 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -63,11 +63,38 @@ pci_max_busnr(void)
return max;
}
+static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap)
+{
+ u8 id;
+ int ttl = 48;
+
+ while (ttl--) {
+ pci_bus_read_config_byte(bus, devfn, pos, &pos);
+ if (pos < 0x40)
+ break;
+ pos &= ~3;
+ pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID,
+ &id);
+ if (id == 0xff)
+ break;
+ if (id == cap)
+ return pos;
+ pos += PCI_CAP_LIST_NEXT;
+ }
+ return 0;
+}
+
+int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
+{
+ return __pci_find_next_cap(dev->bus, dev->devfn,
+ pos + PCI_CAP_LIST_NEXT, cap);
+}
+EXPORT_SYMBOL_GPL(pci_find_next_capability);
+
static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap)
{
u16 status;
- u8 pos, id;
- int ttl = 48;
+ u8 pos;
pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
if (!(status & PCI_STATUS_CAP_LIST))
@@ -76,24 +103,15 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty
switch (hdr_type) {
case PCI_HEADER_TYPE_NORMAL:
case PCI_HEADER_TYPE_BRIDGE:
- pci_bus_read_config_byte(bus, devfn, PCI_CAPABILITY_LIST, &pos);
+ pos = PCI_CAPABILITY_LIST;
break;
case PCI_HEADER_TYPE_CARDBUS:
- pci_bus_read_config_byte(bus, devfn, PCI_CB_CAPABILITY_LIST, &pos);
+ pos = PCI_CB_CAPABILITY_LIST;
break;
default:
return 0;
}
- while (ttl-- && pos >= 0x40) {
- pos &= ~3;
- pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID, &id);
- if (id == 0xff)
- break;
- if (id == cap)
- return pos;
- pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_NEXT, &pos);
- }
- return 0;
+ return __pci_find_next_cap(bus, devfn, pos, cap);
}
/**
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 5627ce1..3a4f49f 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -462,11 +462,11 @@ static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev)
pci_read_config_word(dev, 0x70, &hm);
hm &= PCI_BASE_ADDRESS_IO_MASK;
- quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c868 HW-mon");
+ quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon");
pci_read_config_dword(dev, 0x90, &smb);
smb &= PCI_BASE_ADDRESS_IO_MASK;
- quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c868 SMB");
+ quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB");
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi );
@@ -1243,6 +1243,21 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos);
+
+static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
+{
+ /* rev 1 ncr53c810 chips don't set the class at all which means
+ * they don't get their resources remapped. Fix that here.
+ */
+
+ if (dev->class == PCI_CLASS_NOT_DEFINED) {
+ printk(KERN_INFO "NCR 53c810 rev 1 detected, setting PCI class.\n");
+ dev->class = PCI_CLASS_STORAGE_SCSI;
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
+
+
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
{
while (f < end) {
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 234cdca..a30aa74 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -513,6 +513,11 @@ static int socket_insert(struct pcmcia_socket *skt)
ret = socket_setup(skt, setup_delay);
if (ret == CS_SUCCESS) {
skt->state |= SOCKET_PRESENT;
+
+ printk(KERN_NOTICE "pccard: %s card inserted into slot %d\n",
+ (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
+ skt->sock);
+
#ifdef CONFIG_CARDBUS
if (skt->state & SOCKET_CARDBUS) {
cb_alloc(skt);
@@ -598,6 +603,7 @@ static int socket_resume(struct pcmcia_socket *skt)
static void socket_remove(struct pcmcia_socket *skt)
{
+ printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock);
socket_shutdown(skt);
cs_socket_put(skt);
}
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 39d096b..7f8219f 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -544,6 +544,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
list_add_tail(&p_dev->socket_device_list, &s->devices_list);
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ printk(KERN_NOTICE "pcmcia: registering new device %s\n",
+ p_dev->devname);
+
pcmcia_device_query(p_dev);
if (device_register(&p_dev->dev)) {
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 4ddd762..4d56bc9 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1339,10 +1339,7 @@ static struct device_driver i82365_driver = {
.resume = pcmcia_socket_dev_resume,
};
-static struct platform_device i82365_device = {
- .name = "i82365",
- .id = 0,
-};
+static struct platform_device *i82365_device;
static int __init init_i82365(void)
{
@@ -1352,7 +1349,14 @@ static int __init init_i82365(void)
if (ret)
return ret;
- ret = platform_device_register(&i82365_device);
+ i82365_device = platform_device_alloc("i82365", 0);
+ if (i82365_device) {
+ ret = platform_device_add(i82365_device);
+ if (ret)
+ platform_device_put(i82365_device);
+ } else
+ ret = -ENOMEM;
+
if (ret) {
driver_unregister(&i82365_driver);
return ret;
@@ -1365,7 +1369,7 @@ static int __init init_i82365(void)
if (sockets == 0) {
printk("not found.\n");
- platform_device_unregister(&i82365_device);
+ platform_device_unregister(i82365_device);
release_region(i365_base, 2);
driver_unregister(&i82365_driver);
return -ENODEV;
@@ -1377,7 +1381,7 @@ static int __init init_i82365(void)
/* register sockets with the pcmcia core */
for (i = 0; i < sockets; i++) {
- socket[i].socket.dev.dev = &i82365_device.dev;
+ socket[i].socket.dev.dev = &i82365_device->dev;
socket[i].socket.ops = &pcic_operations;
socket[i].socket.resource_ops = &pccard_nonstatic_ops;
socket[i].socket.owner = THIS_MODULE;
@@ -1415,7 +1419,7 @@ static void __exit exit_i82365(void)
if (socket[i].flags & IS_REGISTERED)
pcmcia_unregister_socket(&socket[i].socket);
}
- platform_device_unregister(&i82365_device);
+ platform_device_unregister(i82365_device);
if (poll_interval != 0)
del_timer_sync(&poll_timer);
if (grab_irq != 0)
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index f5b7d36..1026f2b 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -1179,12 +1179,12 @@ raw3270_create_attributes(struct raw3270 *rp)
//FIXME: check return code
sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
rp->clttydev =
- class_device_create(class3270,
+ class_device_create(class3270, NULL,
MKDEV(IBM_TTY3270_MAJOR, rp->minor),
&rp->cdev->dev, "tty%s",
rp->cdev->dev.bus_id);
rp->cltubdev =
- class_device_create(class3270,
+ class_device_create(class3270, NULL,
MKDEV(IBM_FS3270_MAJOR, rp->minor),
&rp->cdev->dev, "tub%s",
rp->cdev->dev.bus_id);
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 1c8ad2f..da8c515 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -8,7 +8,7 @@
* Author(s): Original Code written by
* DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
* Rewritten by
- * Frank Pavlic (pavlic@de.ibm.com) and
+ * Frank Pavlic (fpavlic@de.ibm.com) and
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*
* $Revision: 1.99 $ $Date: 2005/05/11 08:10:17 $
@@ -2342,6 +2342,6 @@ __exit lcs_cleanup_module(void)
module_init(lcs_init_module);
module_exit(lcs_cleanup_module);
-MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");
+MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 38a2441..d238c7e 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -8,6 +8,7 @@
#include <linux/trdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
+#include <linux/ctype.h>
#include <net/ipv6.h>
#include <linux/in6.h>
@@ -24,7 +25,7 @@
#include "qeth_mpc.h"
-#define VERSION_QETH_H "$Revision: 1.142 $"
+#define VERSION_QETH_H "$Revision: 1.152 $"
#ifdef CONFIG_QETH_IPV6
#define QETH_VERSION_IPV6 ":IPv6"
@@ -718,8 +719,6 @@ struct qeth_reply {
atomic_t refcnt;
};
-#define QETH_BROADCAST_WITH_ECHO 1
-#define QETH_BROADCAST_WITHOUT_ECHO 2
struct qeth_card_blkt {
int time_total;
@@ -727,8 +726,10 @@ struct qeth_card_blkt {
int inter_packet_jumbo;
};
-
-
+#define QETH_BROADCAST_WITH_ECHO 0x01
+#define QETH_BROADCAST_WITHOUT_ECHO 0x02
+#define QETH_LAYER2_MAC_READ 0x01
+#define QETH_LAYER2_MAC_REGISTERED 0x02
struct qeth_card_info {
unsigned short unit_addr2;
unsigned short cula;
@@ -736,7 +737,7 @@ struct qeth_card_info {
__u16 func_level;
char mcl_level[QETH_MCL_LENGTH + 1];
int guestlan;
- int layer2_mac_registered;
+ int mac_bits;
int portname_required;
int portno;
char portname[9];
@@ -749,6 +750,7 @@ struct qeth_card_info {
int unique_id;
struct qeth_card_blkt blkt;
__u32 csum_mask;
+ enum qeth_ipa_promisc_modes promisc_mode;
};
struct qeth_card_options {
@@ -775,6 +777,7 @@ struct qeth_card_options {
enum qeth_threads {
QETH_SET_IP_THREAD = 1,
QETH_RECOVER_THREAD = 2,
+ QETH_SET_PROMISC_MODE_THREAD = 4,
};
struct qeth_osn_info {
@@ -1074,6 +1077,26 @@ qeth_get_qdio_q_format(struct qeth_card *card)
}
}
+static inline int
+qeth_isdigit(char * buf)
+{
+ while (*buf) {
+ if (!isdigit(*buf++))
+ return 0;
+ }
+ return 1;
+}
+
+static inline int
+qeth_isxdigit(char * buf)
+{
+ while (*buf) {
+ if (!isxdigit(*buf++))
+ return 0;
+ }
+ return 1;
+}
+
static inline void
qeth_ipaddr4_to_string(const __u8 *addr, char *buf)
{
@@ -1090,18 +1113,27 @@ qeth_string_to_ipaddr4(const char *buf, __u8 *addr)
int i;
start = buf;
- for (i = 0; i < 3; i++) {
- if (!(end = strchr(start, '.')))
+ for (i = 0; i < 4; i++) {
+ if (i == 3) {
+ end = strchr(start,0xa);
+ if (end)
+ len = end - start;
+ else
+ len = strlen(start);
+ }
+ else {
+ end = strchr(start, '.');
+ len = end - start;
+ }
+ if ((len <= 0) || (len > 3))
return -EINVAL;
- len = end - start;
memset(abuf, 0, 4);
strncpy(abuf, start, len);
+ if (!qeth_isdigit(abuf))
+ return -EINVAL;
addr[i] = simple_strtoul(abuf, &tmp, 10);
start = end + 1;
}
- memset(abuf, 0, 4);
- strcpy(abuf, start);
- addr[3] = simple_strtoul(abuf, &tmp, 10);
return 0;
}
@@ -1128,18 +1160,27 @@ qeth_string_to_ipaddr6(const char *buf, __u8 *addr)
tmp_addr = (u16 *)addr;
start = buf;
- for (i = 0; i < 7; i++) {
- if (!(end = strchr(start, ':')))
+ for (i = 0; i < 8; i++) {
+ if (i == 7) {
+ end = strchr(start,0xa);
+ if (end)
+ len = end - start;
+ else
+ len = strlen(start);
+ }
+ else {
+ end = strchr(start, ':');
+ len = end - start;
+ }
+ if ((len <= 0) || (len > 4))
return -EINVAL;
- len = end - start;
memset(abuf, 0, 5);
strncpy(abuf, start, len);
+ if (!qeth_isxdigit(abuf))
+ return -EINVAL;
tmp_addr[i] = simple_strtoul(abuf, &tmp, 16);
start = end + 1;
}
- memset(abuf, 0, 5);
- strcpy(abuf, start);
- tmp_addr[7] = simple_strtoul(abuf, &tmp, 16);
return 0;
}
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 692003c..99cceb2 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1,6 +1,6 @@
/*
*
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.224 $)
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.242 $)
*
* Linux on zSeries OSA Express and HiperSockets support
*
@@ -9,10 +9,10 @@
* Author(s): Original Code written by
* Utz Bacher (utz.bacher@de.ibm.com)
* Rewritten by
- * Frank Pavlic (pavlic@de.ibm.com) and
+ * Frank Pavlic (fpavlic@de.ibm.com) and
* Thomas Spatzier <tspat@de.ibm.com>
*
- * $Revision: 1.224 $ $Date: 2005/05/04 20:19:18 $
+ * $Revision: 1.242 $ $Date: 2005/05/04 20:19:18 $
*
* 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
@@ -72,7 +72,7 @@
#include "qeth_eddp.h"
#include "qeth_tso.h"
-#define VERSION_QETH_C "$Revision: 1.224 $"
+#define VERSION_QETH_C "$Revision: 1.242 $"
static const char *version = "qeth S/390 OSA-Express driver";
/**
@@ -160,6 +160,9 @@ static void
qeth_set_multicast_list(struct net_device *);
static void
+qeth_setadp_promisc_mode(struct qeth_card *);
+
+static void
qeth_notify_processes(void)
{
/*notify all registered processes */
@@ -602,11 +605,20 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
int found = 0;
list_for_each_entry(addr, &card->ip_list, entry) {
+ if (card->options.layer2) {
+ if ((addr->type == todo->type) &&
+ (memcmp(&addr->mac, &todo->mac,
+ OSA_ADDR_LEN) == 0)) {
+ found = 1;
+ break;
+ }
+ continue;
+ }
if ((addr->proto == QETH_PROT_IPV4) &&
(todo->proto == QETH_PROT_IPV4) &&
(addr->type == todo->type) &&
(addr->u.a4.addr == todo->u.a4.addr) &&
- (addr->u.a4.mask == todo->u.a4.mask) ){
+ (addr->u.a4.mask == todo->u.a4.mask)) {
found = 1;
break;
}
@@ -615,12 +627,12 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
(addr->type == todo->type) &&
(addr->u.a6.pfxlen == todo->u.a6.pfxlen) &&
(memcmp(&addr->u.a6.addr, &todo->u.a6.addr,
- sizeof(struct in6_addr)) == 0)) {
+ sizeof(struct in6_addr)) == 0)) {
found = 1;
break;
}
}
- if (found){
+ if (found) {
addr->users += todo->users;
if (addr->users <= 0){
*__addr = addr;
@@ -632,7 +644,7 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
return 0;
}
}
- if (todo->users > 0){
+ if (todo->users > 0) {
/* for VIPA and RXIP limit refcount to 1 */
if (todo->type != QETH_IP_TYPE_NORMAL)
todo->users = 1;
@@ -682,12 +694,22 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
(tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
return 0;
+ if (card->options.layer2) {
+ if ((tmp->type == addr->type) &&
+ (tmp->is_multicast == addr->is_multicast) &&
+ (memcmp(&tmp->mac, &addr->mac,
+ OSA_ADDR_LEN) == 0)) {
+ found = 1;
+ break;
+ }
+ continue;
+ }
if ((tmp->proto == QETH_PROT_IPV4) &&
(addr->proto == QETH_PROT_IPV4) &&
(tmp->type == addr->type) &&
(tmp->is_multicast == addr->is_multicast) &&
(tmp->u.a4.addr == addr->u.a4.addr) &&
- (tmp->u.a4.mask == addr->u.a4.mask) ){
+ (tmp->u.a4.mask == addr->u.a4.mask)) {
found = 1;
break;
}
@@ -697,7 +719,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
(tmp->is_multicast == addr->is_multicast) &&
(tmp->u.a6.pfxlen == addr->u.a6.pfxlen) &&
(memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
- sizeof(struct in6_addr)) == 0) ){
+ sizeof(struct in6_addr)) == 0)) {
found = 1;
break;
}
@@ -707,7 +729,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
tmp->users += addr->users;
else
tmp->users += add? 1:-1;
- if (tmp->users == 0){
+ if (tmp->users == 0) {
list_del(&tmp->entry);
kfree(tmp);
}
@@ -738,12 +760,15 @@ qeth_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
unsigned long flags;
int rc = 0;
- QETH_DBF_TEXT(trace,4,"delip");
- if (addr->proto == QETH_PROT_IPV4)
- QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4);
+ QETH_DBF_TEXT(trace, 4, "delip");
+
+ if (card->options.layer2)
+ QETH_DBF_HEX(trace, 4, &addr->mac, 6);
+ else if (addr->proto == QETH_PROT_IPV4)
+ QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
else {
- QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8);
- QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8);
+ QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
+ QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
}
spin_lock_irqsave(&card->ip_lock, flags);
rc = __qeth_insert_ip_todo(card, addr, 0);
@@ -757,12 +782,14 @@ qeth_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
unsigned long flags;
int rc = 0;
- QETH_DBF_TEXT(trace,4,"addip");
- if (addr->proto == QETH_PROT_IPV4)
- QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4);
+ QETH_DBF_TEXT(trace, 4, "addip");
+ if (card->options.layer2)
+ QETH_DBF_HEX(trace, 4, &addr->mac, 6);
+ else if (addr->proto == QETH_PROT_IPV4)
+ QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
else {
- QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8);
- QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8);
+ QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
+ QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
}
spin_lock_irqsave(&card->ip_lock, flags);
rc = __qeth_insert_ip_todo(card, addr, 1);
@@ -775,7 +802,7 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
{
struct qeth_ipaddr *addr, *tmp;
int rc;
-
+again:
list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {
if (addr->is_multicast) {
spin_unlock_irqrestore(&card->ip_lock, *flags);
@@ -784,6 +811,7 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
if (!rc) {
list_del(&addr->entry);
kfree(addr);
+ goto again;
}
}
}
@@ -851,6 +879,7 @@ qeth_set_ip_addr_list(struct qeth_card *card)
static void qeth_delete_mc_addresses(struct qeth_card *);
static void qeth_add_multicast_ipv4(struct qeth_card *);
+static void qeth_layer2_add_multicast(struct qeth_card *);
#ifdef CONFIG_QETH_IPV6
static void qeth_add_multicast_ipv6(struct qeth_card *);
#endif
@@ -939,6 +968,24 @@ qeth_register_ip_addresses(void *ptr)
return 0;
}
+/*
+ * Drive the SET_PROMISC_MODE thread
+ */
+static int
+qeth_set_promisc_mode(void *ptr)
+{
+ struct qeth_card *card = (struct qeth_card *) ptr;
+
+ daemonize("qeth_setprm");
+ QETH_DBF_TEXT(trace,4,"setprm1");
+ if (!qeth_do_run_thread(card, QETH_SET_PROMISC_MODE_THREAD))
+ return 0;
+ QETH_DBF_TEXT(trace,4,"setprm2");
+ qeth_setadp_promisc_mode(card);
+ qeth_clear_thread_running_bit(card, QETH_SET_PROMISC_MODE_THREAD);
+ return 0;
+}
+
static int
qeth_recover(void *ptr)
{
@@ -1005,6 +1052,8 @@ qeth_start_kernel_thread(struct qeth_card *card)
if (qeth_do_start_thread(card, QETH_SET_IP_THREAD))
kernel_thread(qeth_register_ip_addresses, (void *)card,SIGCHLD);
+ if (qeth_do_start_thread(card, QETH_SET_PROMISC_MODE_THREAD))
+ kernel_thread(qeth_set_promisc_mode, (void *)card, SIGCHLD);
if (qeth_do_start_thread(card, QETH_RECOVER_THREAD))
kernel_thread(qeth_recover, (void *) card, SIGCHLD);
}
@@ -3749,7 +3798,7 @@ qeth_open(struct net_device *dev)
if ( (card->info.type != QETH_CARD_TYPE_OSN) &&
(card->options.layer2) &&
- (!card->info.layer2_mac_registered)) {
+ (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))) {
QETH_DBF_TEXT(trace,4,"nomacadr");
return -EPERM;
}
@@ -4311,6 +4360,8 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
out:
if (flush_count)
qeth_flush_buffers(queue, 0, start_index, flush_count);
+ else if (!atomic_read(&queue->set_pci_flags_count))
+ atomic_swap(&queue->state, QETH_OUT_Q_LOCKED_FLUSH);
/*
* queue->state will go from LOCKED -> UNLOCKED or from
* LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us
@@ -4975,6 +5026,10 @@ qeth_default_setassparms_cb(struct qeth_card *, struct qeth_reply *,
unsigned long);
static int
+qeth_default_setadapterparms_cb(struct qeth_card *card,
+ struct qeth_reply *reply,
+ unsigned long data);
+static int
qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *,
__u16, long,
int (*reply_cb)
@@ -5301,8 +5356,7 @@ qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid)
struct qeth_ipaddr *addr;
QETH_DBF_TEXT(trace, 4, "frvaddr4");
- if (!card->vlangrp)
- return;
+
rcu_read_lock();
in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]);
if (!in_dev)
@@ -5330,8 +5384,7 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid)
struct qeth_ipaddr *addr;
QETH_DBF_TEXT(trace, 4, "frvaddr6");
- if (!card->vlangrp)
- return;
+
in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]);
if (!in6_dev)
return;
@@ -5351,10 +5404,38 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid)
}
static void
+qeth_free_vlan_addresses(struct qeth_card *card, unsigned short vid)
+{
+ if (card->options.layer2 || !card->vlangrp)
+ return;
+ qeth_free_vlan_addresses4(card, vid);
+ qeth_free_vlan_addresses6(card, vid);
+}
+
+static int
+qeth_layer2_send_setdelvlan_cb(struct qeth_card *card,
+ struct qeth_reply *reply,
+ unsigned long data)
+{
+ struct qeth_ipa_cmd *cmd;
+
+ QETH_DBF_TEXT(trace, 2, "L2sdvcb");
+ cmd = (struct qeth_ipa_cmd *) data;
+ if (cmd->hdr.return_code) {
+ PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
+ "Continuing\n",cmd->data.setdelvlan.vlan_id,
+ QETH_CARD_IFNAME(card), cmd->hdr.return_code);
+ QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command);
+ QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
+ QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
+ }
+ return 0;
+}
+
+static int
qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i,
enum qeth_ipa_cmds ipacmd)
{
- int rc;
struct qeth_ipa_cmd *cmd;
struct qeth_cmd_buffer *iob;
@@ -5362,15 +5443,8 @@ qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i,
iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
cmd->data.setdelvlan.vlan_id = i;
-
- rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
- if (rc) {
- PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
- "Continuing\n",i, QETH_CARD_IFNAME(card), rc);
- QETH_DBF_TEXT_(trace, 2, "L2VL%4x", ipacmd);
- QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
- QETH_DBF_TEXT_(trace, 2, "err%d", rc);
- }
+ return qeth_send_ipa_cmd(card, iob,
+ qeth_layer2_send_setdelvlan_cb, NULL);
}
static void
@@ -5420,8 +5494,7 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
qeth_free_vlan_skbs(card, vid);
spin_lock_irqsave(&card->vlanlock, flags);
/* unregister IP addresses of vlan device */
- qeth_free_vlan_addresses4(card, vid);
- qeth_free_vlan_addresses6(card, vid);
+ qeth_free_vlan_addresses(card, vid);
if (card->vlangrp)
card->vlangrp->vlan_devices[vid] = NULL;
spin_unlock_irqrestore(&card->vlanlock, flags);
@@ -5430,6 +5503,59 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
qeth_set_multicast_list(card->dev);
}
#endif
+/**
+ * Examine hardware response to SET_PROMISC_MODE
+ */
+static int
+qeth_setadp_promisc_mode_cb(struct qeth_card *card,
+ struct qeth_reply *reply,
+ unsigned long data)
+{
+ struct qeth_ipa_cmd *cmd;
+ struct qeth_ipacmd_setadpparms *setparms;
+
+ QETH_DBF_TEXT(trace,4,"prmadpcb");
+
+ cmd = (struct qeth_ipa_cmd *) data;
+ setparms = &(cmd->data.setadapterparms);
+
+ qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
+ if (cmd->hdr.return_code) {
+ QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code);
+ setparms->data.mode = SET_PROMISC_MODE_OFF;
+ }
+ card->info.promisc_mode = setparms->data.mode;
+ return 0;
+}
+/*
+ * Set promiscuous mode (on or off) (SET_PROMISC_MODE command)
+ */
+static void
+qeth_setadp_promisc_mode(struct qeth_card *card)
+{
+ enum qeth_ipa_promisc_modes mode;
+ struct net_device *dev = card->dev;
+ struct qeth_cmd_buffer *iob;
+ struct qeth_ipa_cmd *cmd;
+
+ QETH_DBF_TEXT(trace, 4, "setprom");
+
+ if (((dev->flags & IFF_PROMISC) &&
+ (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
+ (!(dev->flags & IFF_PROMISC) &&
+ (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
+ return;
+ mode = SET_PROMISC_MODE_OFF;
+ if (dev->flags & IFF_PROMISC)
+ mode = SET_PROMISC_MODE_ON;
+ QETH_DBF_TEXT_(trace, 4, "mode:%x", mode);
+
+ iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE,
+ sizeof(struct qeth_ipacmd_setadpparms));
+ cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
+ cmd->data.setadapterparms.data.mode = mode;
+ qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);
+}
/**
* set multicast address on card
@@ -5444,12 +5570,22 @@ qeth_set_multicast_list(struct net_device *dev)
QETH_DBF_TEXT(trace,3,"setmulti");
qeth_delete_mc_addresses(card);
+ if (card->options.layer2) {
+ qeth_layer2_add_multicast(card);
+ goto out;
+ }
qeth_add_multicast_ipv4(card);
#ifdef CONFIG_QETH_IPV6
qeth_add_multicast_ipv6(card);
#endif
+out:
if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
schedule_work(&card->kernel_thread_starter);
+ if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
+ return;
+ if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0)
+ schedule_work(&card->kernel_thread_starter);
+
}
static int
@@ -5657,6 +5793,24 @@ qeth_add_multicast_ipv4(struct qeth_card *card)
in_dev_put(in4_dev);
}
+static void
+qeth_layer2_add_multicast(struct qeth_card *card)
+{
+ struct qeth_ipaddr *ipm;
+ struct dev_mc_list *dm;
+
+ QETH_DBF_TEXT(trace,4,"L2addmc");
+ for (dm = card->dev->mc_list; dm; dm = dm->next) {
+ ipm = qeth_get_addr_buffer(QETH_PROT_IPV4);
+ if (!ipm)
+ continue;
+ memcpy(ipm->mac,dm->dmi_addr,MAX_ADDR_LEN);
+ ipm->is_multicast = 1;
+ if (!qeth_add_ip(card, ipm))
+ kfree(ipm);
+ }
+}
+
#ifdef CONFIG_QETH_IPV6
static inline void
qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)
@@ -5825,10 +5979,10 @@ qeth_layer2_send_setmac_cb(struct qeth_card *card,
PRINT_WARN("Error in registering MAC address on " \
"device %s: x%x\n", CARD_BUS_ID(card),
cmd->hdr.return_code);
- card->info.layer2_mac_registered = 0;
+ card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
cmd->hdr.return_code = -EIO;
} else {
- card->info.layer2_mac_registered = 1;
+ card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac,
OSA_ADDR_LEN);
PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
@@ -5866,7 +6020,7 @@ qeth_layer2_send_delmac_cb(struct qeth_card *card,
cmd->hdr.return_code = -EIO;
return 0;
}
- card->info.layer2_mac_registered = 0;
+ card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
return 0;
}
@@ -5874,7 +6028,7 @@ static int
qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac)
{
QETH_DBF_TEXT(trace, 2, "L2Delmac");
- if (!card->info.layer2_mac_registered)
+ if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
return 0;
return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC,
qeth_layer2_send_delmac_cb);
@@ -5896,7 +6050,7 @@ qeth_layer2_set_mac_address(struct net_device *dev, void *p)
card = (struct qeth_card *) dev->priv;
if (!card->options.layer2) {
- PRINT_WARN("Setting MAC address on %s is not supported"
+ PRINT_WARN("Setting MAC address on %s is not supported "
"in Layer 3 mode.\n", dev->name);
QETH_DBF_TEXT(trace, 3, "setmcLY3");
return -EOPNOTSUPP;
@@ -6441,6 +6595,8 @@ qeth_default_setadapterparms_cb(struct qeth_card *card,
return 0;
}
+
+
static int
qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply,
unsigned long data)
@@ -6481,8 +6637,13 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
QETH_DBF_TEXT(trace,4,"chgmaccb");
cmd = (struct qeth_ipa_cmd *) data;
- memcpy(card->dev->dev_addr,
- &cmd->data.setadapterparms.data.change_addr.addr,OSA_ADDR_LEN);
+ if (!card->options.layer2 || card->info.guestlan ||
+ !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
+ memcpy(card->dev->dev_addr,
+ &cmd->data.setadapterparms.data.change_addr.addr,
+ OSA_ADDR_LEN);
+ card->info.mac_bits |= QETH_LAYER2_MAC_READ;
+ }
qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
return 0;
}
@@ -6602,6 +6763,12 @@ qeth_layer2_initialize(struct qeth_card *card)
QETH_DBF_TEXT(setup, 2, "doL2init");
QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card));
+ rc = qeth_query_setadapterparms(card);
+ if (rc) {
+ PRINT_WARN("could not query adapter parameters on device %s: "
+ "x%x\n", CARD_BUS_ID(card), rc);
+ }
+
rc = qeth_setadpparms_change_macaddr(card);
if (rc) {
PRINT_WARN("couldn't get MAC address on "
@@ -8548,7 +8715,7 @@ EXPORT_SYMBOL(qeth_osn_deregister);
EXPORT_SYMBOL(qeth_osn_assist);
module_init(qeth_init);
module_exit(qeth_exit);
-MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");
+MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>");
MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \
"Copyright 2000,2003 IBM Corporation\n");
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c
index 30e053d..f0a080a 100644
--- a/drivers/s390/net/qeth_mpc.c
+++ b/drivers/s390/net/qeth_mpc.c
@@ -4,7 +4,7 @@
* Linux on zSeries OSA Express and HiperSockets support
*
* Copyright 2000,2003 IBM Corporation
- * Author(s): Frank Pavlic <pavlic@de.ibm.com>
+ * Author(s): Frank Pavlic <fpavlic@de.ibm.com>
* Thomas Spatzier <tspat@de.ibm.com>
*
*/
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h
index 7edc5f1..5f71486 100644
--- a/drivers/s390/net/qeth_mpc.h
+++ b/drivers/s390/net/qeth_mpc.h
@@ -6,7 +6,7 @@
* Copyright 2000,2003 IBM Corporation
* Author(s): Utz Bacher <utz.bacher@de.ibm.com>
* Thomas Spatzier <tspat@de.ibm.com>
- * Frank Pavlic <pavlic@de.ibm.com>
+ * Frank Pavlic <fpavlic@de.ibm.com>
*
*/
#ifndef __QETH_MPC_H__
@@ -14,7 +14,7 @@
#include <asm/qeth.h>
-#define VERSION_QETH_MPC_H "$Revision: 1.43 $"
+#define VERSION_QETH_MPC_H "$Revision: 1.44 $"
extern const char *VERSION_QETH_MPC_C;
@@ -217,7 +217,7 @@ enum qeth_ipa_setadp_cmd {
IPA_SETADP_SEND_OSA_MESSAGE = 0x0100,
IPA_SETADP_SET_SNMP_CONTROL = 0x0200,
IPA_SETADP_READ_SNMP_PARMS = 0x0400,
- IPA_SETADP_WRITE_SNMP_PARMS = 0x0800,
+ IPA_SETADP_SET_PROMISC_MODE = 0x0800,
IPA_SETADP_QUERY_CARD_INFO = 0x1000,
};
enum qeth_ipa_mac_ops {
@@ -232,9 +232,12 @@ enum qeth_ipa_addr_ops {
CHANGE_ADDR_ADD_ADDR = 1,
CHANGE_ADDR_DEL_ADDR = 2,
CHANGE_ADDR_FLUSH_ADDR_TABLE = 4,
-
-
};
+enum qeth_ipa_promisc_modes {
+ SET_PROMISC_MODE_OFF = 0,
+ SET_PROMISC_MODE_ON = 1,
+};
+
/* (SET)DELIP(M) IPA stuff ***************************************************/
struct qeth_ipacmd_setdelip4 {
__u8 ip_addr[4];
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index f91a02d..ddd6019 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -1,6 +1,6 @@
/*
*
- * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.55 $)
+ * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.58 $)
*
* Linux on zSeries OSA Express and HiperSockets support
* This file contains code related to sysfs.
@@ -8,7 +8,7 @@
* Copyright 2000,2003 IBM Corporation
*
* Author(s): Thomas Spatzier <tspat@de.ibm.com>
- * Frank Pavlic <pavlic@de.ibm.com>
+ * Frank Pavlic <fpavlic@de.ibm.com>
*
*/
#include <linux/list.h>
@@ -20,7 +20,7 @@
#include "qeth_mpc.h"
#include "qeth_fs.h"
-const char *VERSION_QETH_SYS_C = "$Revision: 1.55 $";
+const char *VERSION_QETH_SYS_C = "$Revision: 1.58 $";
/*****************************************************************************/
/* */
@@ -1117,7 +1117,7 @@ qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,
start = buf;
/* get address string */
end = strchr(start, '/');
- if (!end){
+ if (!end || (end-start >= 49)){
PRINT_WARN("Invalid format for ipato_addx/delx. "
"Use <ip addr>/<mask bits>\n");
return -EINVAL;
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
index ad33e6f..e245af3 100644
--- a/drivers/s390/net/qeth_tso.h
+++ b/drivers/s390/net/qeth_tso.h
@@ -5,7 +5,7 @@
*
* Copyright 2004 IBM Corporation
*
- * Author(s): Frank Pavlic <pavlic@de.ibm.com>
+ * Author(s): Frank Pavlic <fpavlic@de.ibm.com>
*
* $Revision: 1.7 $ $Date: 2005/05/04 20:19:18 $
*
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 2c86a4b..c3a51d1 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -119,7 +119,7 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
__u8 regs = readb(d7s_regs);
__u8 ireg = 0;
- int error = 0
+ int error = 0;
if (D7S_MINOR != iminor(file->f_dentry->d_inode))
return -ENODEV;
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 5774bdd..9b988ba 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -210,27 +210,6 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
}
-static long rtc_compat_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- int rval = -ENOIOCTLCMD;
-
- switch (cmd) {
- /*
- * These two are specific to this driver, the generic rtc ioctls
- * are hanlded elsewhere.
- */
- case RTCGET:
- case RTCSET:
- lock_kernel();
- rval = rtc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
- unlock_kernel();
- break;
- }
-
- return rval;
-}
-
static int rtc_open(struct inode *inode, struct file *file)
{
int ret;
@@ -258,7 +237,6 @@ static struct file_operations rtc_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = rtc_ioctl,
- .compat_ioctl = rtc_compat_ioctl,
.open = rtc_open,
.release = rtc_release,
};
diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c
index 7a33c70..9cb5dd4 100644
--- a/drivers/scsi/53c7xx.c
+++ b/drivers/scsi/53c7xx.c
@@ -343,7 +343,7 @@ static void NCR53c7x0_soft_reset (struct Scsi_Host *host);
/* Size of event list (per host adapter) */
static int track_events = 0;
static struct Scsi_Host *first_host = NULL; /* Head of list of NCR boards */
-static Scsi_Host_Template *the_template = NULL;
+static struct scsi_host_template *the_template = NULL;
/* NCR53c710 script handling code */
@@ -1103,7 +1103,7 @@ NCR53c7x0_init (struct Scsi_Host *host) {
}
/*
- * Function : int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip,
+ * Function : int ncr53c7xx_init(struct scsi_host_template *tpnt, int board, int chip,
* unsigned long base, int io_port, int irq, int dma, long long options,
* int clock);
*
@@ -1118,7 +1118,7 @@ NCR53c7x0_init (struct Scsi_Host *host) {
*/
int
-ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip,
+ncr53c7xx_init (struct scsi_host_template *tpnt, int board, int chip,
unsigned long base, int io_port, int irq, int dma,
long long options, int clock)
{
diff --git a/drivers/scsi/53c7xx.h b/drivers/scsi/53c7xx.h
index d9098bd..218f3b9 100644
--- a/drivers/scsi/53c7xx.h
+++ b/drivers/scsi/53c7xx.h
@@ -1600,7 +1600,7 @@ struct NCR53c7x0_hostdata {
/* Paranoid people could use panic() here. */
#define FATAL(host) shutdown((host));
-extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip,
+extern int ncr53c7xx_init(struct scsi_host_template *tpnt, int board, int chip,
unsigned long base, int io_port, int irq, int dma,
long long options, int clock);
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index afeca32..20dd85a 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -497,7 +497,7 @@ config SCSI_ATA_PIIX
If unsure, say N.
config SCSI_SATA_MV
- tristate "Marvell SATA support"
+ tristate "Marvell SATA support (HIGHLY EXPERIMENTAL)"
depends on SCSI_SATA && PCI && EXPERIMENTAL
help
This option enables support for the Marvell Serial ATA family.
@@ -1295,27 +1295,6 @@ config SCSI_QLOGIC_FAS
To compile this driver as a module, choose M here: the
module will be called qlogicfas.
-config SCSI_QLOGIC_ISP
- tristate "Qlogic ISP SCSI support (old driver)"
- depends on PCI && SCSI && BROKEN
- ---help---
- This driver works for all QLogic PCI SCSI host adapters (IQ-PCI,
- IQ-PCI-10, IQ_PCI-D) except for the PCI-basic card. (This latter
- card is supported by the "AM53/79C974 PCI SCSI" driver.)
-
- If you say Y here, make sure to choose "BIOS" at the question "PCI
- access mode".
-
- Please read the file <file:Documentation/scsi/qlogicisp.txt>. You
- should also read the SCSI-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here: the
- module will be called qlogicisp.
-
- These days the hardware is also supported by the more modern qla1280
- driver. In doubt use that one instead of qlogicisp.
-
config SCSI_QLOGIC_FC
tristate "Qlogic ISP FC SCSI support"
depends on PCI && SCSI
@@ -1342,14 +1321,6 @@ config SCSI_QLOGIC_1280
To compile this driver as a module, choose M here: the
module will be called qla1280.
-config SCSI_QLOGIC_1280_1040
- bool "Qlogic QLA 1020/1040 SCSI support"
- depends on SCSI_QLOGIC_1280 && SCSI_QLOGIC_ISP!=y
- help
- Say Y here if you have a QLogic ISP1020/1040 SCSI host adapter and
- do not want to use the old driver. This option enables support in
- the qla1280 driver for those host adapters.
-
config SCSI_QLOGICPTI
tristate "PTI Qlogic, ISP Driver"
depends on SBUS && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index b88b8c4..f062ea0 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -78,7 +78,6 @@ obj-$(CONFIG_SCSI_NCR_Q720) += NCR_Q720_mod.o
obj-$(CONFIG_SCSI_SYM53C416) += sym53c416.o
obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o
obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o
-obj-$(CONFIG_SCSI_QLOGIC_ISP) += qlogicisp.o
obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o
obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o
obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx/
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
index 26146a4..640590b 100644
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -529,7 +529,7 @@ void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs)
/* Allocate structure and insert basic data such as SCSI chip frequency
* data and a pointer to the device
*/
-struct NCR_ESP* esp_allocate(Scsi_Host_Template *tpnt, void *esp_dev)
+struct NCR_ESP* esp_allocate(struct scsi_host_template *tpnt, void *esp_dev)
{
struct NCR_ESP *esp, *elink;
struct Scsi_Host *esp_host;
@@ -1006,7 +1006,7 @@ static void esp_exec_cmd(struct NCR_ESP *esp)
struct ESP_regs *eregs = esp->eregs;
struct esp_device *esp_dev;
Scsi_Cmnd *SCptr;
- Scsi_Device *SDptr;
+ struct scsi_device *SDptr;
volatile unchar *cmdp = esp->esp_command;
unsigned char the_esp_command;
int lun, target;
@@ -1687,7 +1687,7 @@ static inline int reconnect_lun(struct NCR_ESP *esp, struct ESP_regs *eregs)
static inline void esp_connect(struct NCR_ESP *esp, struct ESP_regs *eregs,
Scsi_Cmnd *sp)
{
- Scsi_Device *dp = sp->device;
+ struct scsi_device *dp = sp->device;
struct esp_device *esp_dev = dp->hostdata;
if(esp->prev_soff != esp_dev->sync_max_offset ||
@@ -3605,7 +3605,7 @@ out:
}
#endif
-int esp_slave_alloc(Scsi_Device *SDptr)
+int esp_slave_alloc(struct scsi_device *SDptr)
{
struct esp_device *esp_dev =
kmalloc(sizeof(struct esp_device), GFP_ATOMIC);
@@ -3617,7 +3617,7 @@ int esp_slave_alloc(Scsi_Device *SDptr)
return 0;
}
-void esp_slave_destroy(Scsi_Device *SDptr)
+void esp_slave_destroy(struct scsi_device *SDptr)
{
struct NCR_ESP *esp = (struct NCR_ESP *) SDptr->host->hostdata;
diff --git a/drivers/scsi/NCR53C9x.h b/drivers/scsi/NCR53C9x.h
index 06e7edf..65a9b37 100644
--- a/drivers/scsi/NCR53C9x.h
+++ b/drivers/scsi/NCR53C9x.h
@@ -653,7 +653,7 @@ extern int nesps, esps_in_use, esps_running;
/* External functions */
extern void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs);
-extern struct NCR_ESP *esp_allocate(Scsi_Host_Template *, void *);
+extern struct NCR_ESP *esp_allocate(struct scsi_host_template *, void *);
extern void esp_deallocate(struct NCR_ESP *);
extern void esp_release(void);
extern void esp_initialize(struct NCR_ESP *);
@@ -664,6 +664,6 @@ extern int esp_abort(Scsi_Cmnd *);
extern int esp_reset(Scsi_Cmnd *);
extern int esp_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, int length,
int inout);
-extern int esp_slave_alloc(Scsi_Device *);
-extern void esp_slave_destroy(Scsi_Device *);
+extern int esp_slave_alloc(struct scsi_device *);
+extern void esp_slave_destroy(struct scsi_device *);
#endif /* !(NCR53C9X_H) */
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index 1353769..ae37d3a 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -447,7 +447,7 @@ static __inline__ int NCR53c406a_pio_write(unsigned char *request, unsigned int
}
#endif /* USE_PIO */
-static int __init NCR53c406a_detect(Scsi_Host_Template * tpnt)
+static int __init NCR53c406a_detect(struct scsi_host_template * tpnt)
{
int present = 0;
struct Scsi_Host *shpnt = NULL;
@@ -1057,7 +1057,7 @@ MODULE_LICENSE("GPL");
* Use SG_NONE if DMA mode is enabled!
*/
-static Scsi_Host_Template driver_template =
+static struct scsi_host_template driver_template =
{
.proc_name = "NCR53c406a" /* proc_name */,
.name = "NCR53c406a" /* name */,
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index 30a14ba..54996ea 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -172,7 +172,7 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
}
}
-int __init a2091_detect(Scsi_Host_Template *tpnt)
+int __init a2091_detect(struct scsi_host_template *tpnt)
{
static unsigned char called = 0;
struct Scsi_Host *instance;
@@ -233,7 +233,7 @@ static int a2091_bus_reset(Scsi_Cmnd *cmd)
#define HOSTS_C
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "A2901",
.name = "Commodore A2091/A590 SCSI",
.detect = a2091_detect,
diff --git a/drivers/scsi/a2091.h b/drivers/scsi/a2091.h
index 5499397..22d6a13 100644
--- a/drivers/scsi/a2091.h
+++ b/drivers/scsi/a2091.h
@@ -11,7 +11,7 @@
#include <linux/types.h>
-int a2091_detect(Scsi_Host_Template *);
+int a2091_detect(struct scsi_host_template *);
int a2091_release(struct Scsi_Host *);
const char *wd33c93_info(void);
int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
index 306caf5..f425d42 100644
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -168,7 +168,7 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
}
}
-int __init a3000_detect(Scsi_Host_Template *tpnt)
+int __init a3000_detect(struct scsi_host_template *tpnt)
{
wd33c93_regs regs;
@@ -221,7 +221,7 @@ static int a3000_bus_reset(Scsi_Cmnd *cmd)
#define HOSTS_C
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "A3000",
.name = "Amiga 3000 built-in SCSI",
.detect = a3000_detect,
diff --git a/drivers/scsi/a3000.h b/drivers/scsi/a3000.h
index b1eda73..5535a65 100644
--- a/drivers/scsi/a3000.h
+++ b/drivers/scsi/a3000.h
@@ -11,7 +11,7 @@
#include <linux/types.h>
-int a3000_detect(Scsi_Host_Template *);
+int a3000_detect(struct scsi_host_template *);
int a3000_release(struct Scsi_Host *);
const char *wd33c93_info(void);
int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 2a128a1..7139659 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1579,18 +1579,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
break;
{
u64 capacity;
- char cp[12];
- unsigned int offset = 0;
+ char cp[13];
dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n"));
capacity = fsa_dev_ptr[cid].size - 1;
- if (scsicmd->cmnd[13] > 12) {
- offset = scsicmd->cmnd[13] - 12;
- if (offset > sizeof(cp))
- break;
- memset(cp, 0, offset);
- aac_internal_transfer(scsicmd, cp, 0, offset);
- }
cp[0] = (capacity >> 56) & 0xff;
cp[1] = (capacity >> 48) & 0xff;
cp[2] = (capacity >> 40) & 0xff;
@@ -1603,7 +1595,18 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
cp[9] = 0;
cp[10] = 2;
cp[11] = 0;
- aac_internal_transfer(scsicmd, cp, offset, sizeof(cp));
+ cp[12] = 0;
+ aac_internal_transfer(scsicmd, cp, 0,
+ min((unsigned int)scsicmd->cmnd[13], sizeof(cp)));
+ if (sizeof(cp) < scsicmd->cmnd[13]) {
+ unsigned int len, offset = sizeof(cp);
+
+ memset(cp, 0, offset);
+ do {
+ len = min(scsicmd->cmnd[13]-offset, sizeof(cp));
+ aac_internal_transfer(scsicmd, cp, offset, len);
+ } while ((offset += len) < scsicmd->cmnd[13]);
+ }
/* Do not cache partition table for arrays */
scsicmd->device->removable = 1;
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 723c0ce..38d6d00 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -820,7 +820,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
break;
/*
- * Find the Scsi_Device associated with the SCSI
+ * Find the scsi_device associated with the SCSI
* address. Make sure we have the right array, and if
* so set the flag to initiate a new re-config once we
* see an AifEnConfigChange AIF come through.
@@ -987,7 +987,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
/*
- * Find the Scsi_Device associated with the SCSI address,
+ * Find the scsi_device associated with the SCSI address,
* and mark it as changed, invalidating the cache. This deals
* with changes to existing device IDs.
*/
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index f4cfb8f..28b9305 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -114,7 +114,7 @@
#include "advansys.h"
#endif
- and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
+ and after "static struct scsi_host_template builtin_scsi_hosts[] =":
#ifdef CONFIG_SCSI_ADVANSYS
ADVANSYS,
@@ -160,7 +160,7 @@
--- Driver Structures
--- Driver Data
--- Driver Function Prototypes
- --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
+ --- Linux 'struct scsi_host_template' and advansys_setup() Functions
--- Loadable Driver Support
--- Miscellaneous Driver Functions
--- Functions Required by the Asc Library
@@ -4068,7 +4068,7 @@ STATIC void asc_prt_hex(char *f, uchar *, int);
/*
- * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
+ * --- Linux 'struct scsi_host_template' and advansys_setup() Functions
*/
#ifdef CONFIG_PROC_FS
diff --git a/drivers/scsi/advansys.h b/drivers/scsi/advansys.h
index 3f4bde0..8ee7fb1 100644
--- a/drivers/scsi/advansys.h
+++ b/drivers/scsi/advansys.h
@@ -19,7 +19,7 @@
#define _ADVANSYS_H
/*
- * Scsi_Host_Template function prototypes.
+ * struct scsi_host_template function prototypes.
*/
int advansys_detect(struct scsi_host_template *);
int advansys_release(struct Scsi_Host *);
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 9b7caf5..9df23b6 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -424,7 +424,7 @@ MODULE_DEVICE_TABLE(isapnp, id_table);
static int registered_count=0;
static struct Scsi_Host *aha152x_host[2];
-static Scsi_Host_Template aha152x_driver_template;
+static struct scsi_host_template aha152x_driver_template;
/*
* internal states of the host
@@ -3464,7 +3464,7 @@ static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start
return thislength < length ? thislength : length;
}
-static Scsi_Host_Template aha152x_driver_template = {
+static struct scsi_host_template aha152x_driver_template = {
.module = THIS_MODULE,
.name = AHA152X_REVID,
.proc_name = "aha152x",
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 1b1adfb..51bad7a 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -1021,7 +1021,7 @@ __setup("aha1542=",do_setup);
#endif
/* return non-zero on detection */
-static int __init aha1542_detect(Scsi_Host_Template * tpnt)
+static int __init aha1542_detect(struct scsi_host_template * tpnt)
{
unsigned char dma_chan;
unsigned char irq_level;
@@ -1789,7 +1789,7 @@ static int aha1542_biosparam(struct scsi_device *sdev,
MODULE_LICENSE("GPL");
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "aha1542",
.name = "Adaptec 1542",
.detect = aha1542_detect,
diff --git a/drivers/scsi/aha1542.h b/drivers/scsi/aha1542.h
index 3821ee1..1db5385 100644
--- a/drivers/scsi/aha1542.h
+++ b/drivers/scsi/aha1542.h
@@ -131,7 +131,7 @@ struct ccb { /* Command Control Block 5.3 */
/* REQUEST SENSE */
};
-static int aha1542_detect(Scsi_Host_Template *);
+static int aha1542_detect(struct scsi_host_template *);
static int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int aha1542_bus_reset(Scsi_Cmnd * SCpnt);
static int aha1542_dev_reset(Scsi_Cmnd * SCpnt);
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
index 8f85dcc..4b8c6a5 100644
--- a/drivers/scsi/aha1740.c
+++ b/drivers/scsi/aha1740.c
@@ -570,7 +570,7 @@ static int aha1740_eh_abort_handler (Scsi_Cmnd *dummy)
return 0;
}
-static Scsi_Host_Template aha1740_template = {
+static struct scsi_host_template aha1740_template = {
.module = THIS_MODULE,
.proc_name = "aha1740",
.proc_info = aha1740_proc_info,
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 10c470e..83467a0 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -48,7 +48,7 @@
#include <asm/io.h>
#define DRV_NAME "ahci"
-#define DRV_VERSION "1.01"
+#define DRV_VERSION "1.2"
enum {
@@ -134,6 +134,7 @@ enum {
PORT_IRQ_D2H_REG_FIS,
/* PORT_CMD bits */
+ PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */
PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */
PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */
PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */
@@ -255,7 +256,7 @@ static struct ata_port_info ahci_port_info[] = {
},
};
-static struct pci_device_id ahci_pci_tbl[] = {
+static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_ahci }, /* ICH6 */
{ PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
@@ -441,7 +442,7 @@ static void ahci_phy_reset(struct ata_port *ap)
void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
struct ata_taskfile tf;
struct ata_device *dev = &ap->device[0];
- u32 tmp;
+ u32 new_tmp, tmp;
__sata_phy_reset(ap);
@@ -455,8 +456,21 @@ static void ahci_phy_reset(struct ata_port *ap)
tf.nsect = (tmp) & 0xff;
dev->class = ata_dev_classify(&tf);
- if (!ata_dev_present(dev))
+ if (!ata_dev_present(dev)) {
ata_port_disable(ap);
+ return;
+ }
+
+ /* Make sure port's ATAPI bit is set appropriately */
+ new_tmp = tmp = readl(port_mmio + PORT_CMD);
+ if (dev->class == ATA_DEV_ATAPI)
+ new_tmp |= PORT_CMD_ATAPI;
+ else
+ new_tmp &= ~PORT_CMD_ATAPI;
+ if (new_tmp != tmp) {
+ writel(new_tmp, port_mmio + PORT_CMD);
+ readl(port_mmio + PORT_CMD); /* flush */
+ }
}
static u8 ahci_check_status(struct ata_port *ap)
@@ -474,11 +488,12 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
ata_tf_from_fis(d2h_fis, tf);
}
-static void ahci_fill_sg(struct ata_queued_cmd *qc)
+static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc)
{
struct ahci_port_priv *pp = qc->ap->private_data;
struct scatterlist *sg;
struct ahci_sg *ahci_sg;
+ unsigned int n_sg = 0;
VPRINTK("ENTER\n");
@@ -493,8 +508,12 @@ static void ahci_fill_sg(struct ata_queued_cmd *qc)
ahci_sg->addr = cpu_to_le32(addr & 0xffffffff);
ahci_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
ahci_sg->flags_size = cpu_to_le32(sg_len - 1);
+
ahci_sg++;
+ n_sg++;
}
+
+ return n_sg;
}
static void ahci_qc_prep(struct ata_queued_cmd *qc)
@@ -503,13 +522,14 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
struct ahci_port_priv *pp = ap->private_data;
u32 opts;
const u32 cmd_fis_len = 5; /* five dwords */
+ unsigned int n_elem;
/*
* Fill in command slot information (currently only one slot,
* slot 0, is currently since we don't do queueing)
*/
- opts = (qc->n_elem << 16) | cmd_fis_len;
+ opts = cmd_fis_len;
if (qc->tf.flags & ATA_TFLAG_WRITE)
opts |= AHCI_CMD_WRITE;
if (is_atapi_taskfile(&qc->tf))
@@ -533,16 +553,31 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
if (!(qc->flags & ATA_QCFLAG_DMAMAP))
return;
- ahci_fill_sg(qc);
+ n_elem = ahci_fill_sg(qc);
+
+ pp->cmd_slot[0].opts |= cpu_to_le32(n_elem << 16);
}
-static void ahci_intr_error(struct ata_port *ap, u32 irq_stat)
+static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
{
void __iomem *mmio = ap->host_set->mmio_base;
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
u32 tmp;
int work;
+ if ((ap->device[0].class != ATA_DEV_ATAPI) ||
+ ((irq_stat & PORT_IRQ_TF_ERR) == 0))
+ printk(KERN_WARNING "ata%u: port reset, "
+ "p_is %x is %x pis %x cmd %x tf %x ss %x se %x\n",
+ ap->id,
+ irq_stat,
+ readl(mmio + HOST_IRQ_STAT),
+ readl(port_mmio + PORT_IRQ_STAT),
+ readl(port_mmio + PORT_CMD),
+ readl(port_mmio + PORT_TFDATA),
+ readl(port_mmio + PORT_SCR_STAT),
+ readl(port_mmio + PORT_SCR_ERR));
+
/* stop DMA */
tmp = readl(port_mmio + PORT_CMD);
tmp &= ~PORT_CMD_START;
@@ -580,8 +615,6 @@ static void ahci_intr_error(struct ata_port *ap, u32 irq_stat)
tmp |= PORT_CMD_START;
writel(tmp, port_mmio + PORT_CMD);
readl(port_mmio + PORT_CMD); /* flush */
-
- printk(KERN_WARNING "ata%u: error occurred, port reset\n", ap->id);
}
static void ahci_eng_timeout(struct ata_port *ap)
@@ -592,17 +625,17 @@ static void ahci_eng_timeout(struct ata_port *ap)
struct ata_queued_cmd *qc;
unsigned long flags;
- DPRINTK("ENTER\n");
+ printk(KERN_WARNING "ata%u: handling error/timeout\n", ap->id);
spin_lock_irqsave(&host_set->lock, flags);
- ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT));
-
qc = ata_qc_from_tag(ap, ap->active_tag);
if (!qc) {
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
ap->id);
} else {
+ ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT));
+
/* hack alert! We cannot use the supplied completion
* function from inside the ->eh_strategy_handler() thread.
* libata is the only user of ->eh_strategy_handler() in
@@ -637,9 +670,19 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
}
if (status & PORT_IRQ_FATAL) {
- ahci_intr_error(ap, status);
+ unsigned int err_mask;
+ if (status & PORT_IRQ_TF_ERR)
+ err_mask = AC_ERR_DEV;
+ else if (status & PORT_IRQ_IF_ERR)
+ err_mask = AC_ERR_ATA_BUS;
+ else
+ err_mask = AC_ERR_HOST_BUS;
+
+ /* command processing has stopped due to error; restart */
+ ahci_restart_port(ap, status);
+
if (qc)
- ata_qc_complete(qc, AC_ERR_OTHER);
+ ata_qc_complete(qc, err_mask);
}
return 1;
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index cfb46c2..31e9f40 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -436,29 +436,20 @@ ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
{
struct ahd_softc *ahd;
struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device);
+ int rtn = SCSI_MLQUEUE_HOST_BUSY;
+ unsigned long flags;
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
- /*
- * Close the race of a command that was in the process of
- * being queued to us just as our simq was frozen. Let
- * DV commands through so long as we are only frozen to
- * perform DV.
- */
- if (ahd->platform_data->qfrozen != 0) {
- printf("%s: queue frozen\n", ahd_name(ahd));
+ ahd_lock(ahd, &flags);
+ if (ahd->platform_data->qfrozen == 0) {
+ cmd->scsi_done = scsi_done;
+ cmd->result = CAM_REQ_INPROG << 16;
+ rtn = ahd_linux_run_command(ahd, dev, cmd);
- return SCSI_MLQUEUE_HOST_BUSY;
}
-
- /*
- * Save the callback on completion function.
- */
- cmd->scsi_done = scsi_done;
-
- cmd->result = CAM_REQ_INPROG << 16;
-
- return ahd_linux_run_command(ahd, dev, cmd);
+ ahd_unlock(ahd, &flags);
+ return rtn;
}
static inline struct scsi_target **
@@ -1081,7 +1072,6 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa
*((struct ahd_softc **)host->hostdata) = ahd;
ahd_lock(ahd, &s);
- scsi_assign_lock(host, &ahd->platform_data->spin_lock);
ahd->platform_data->host = host;
host->can_queue = AHD_MAX_QUEUE;
host->cmd_per_lun = 2;
@@ -2062,6 +2052,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
int wait;
int disconnected;
ahd_mode_state saved_modes;
+ unsigned long flags;
pending_scb = NULL;
paused = FALSE;
@@ -2077,7 +2068,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
printf(" 0x%x", cmd->cmnd[cdb_byte]);
printf("\n");
- spin_lock_irq(&ahd->platform_data->spin_lock);
+ ahd_lock(ahd, &flags);
/*
* First determine if we currently own this command.
@@ -2291,7 +2282,8 @@ done:
int ret;
ahd->platform_data->flags |= AHD_SCB_UP_EH_SEM;
- spin_unlock_irq(&ahd->platform_data->spin_lock);
+ ahd_unlock(ahd, &flags);
+
init_timer(&timer);
timer.data = (u_long)ahd;
timer.expires = jiffies + (5 * HZ);
@@ -2305,9 +2297,8 @@ done:
printf("Timer Expired\n");
retval = FAILED;
}
- spin_lock_irq(&ahd->platform_data->spin_lock);
}
- spin_unlock_irq(&ahd->platform_data->spin_lock);
+ ahd_unlock(ahd, &flags);
return (retval);
}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 1861407..7fc6454 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -476,26 +476,20 @@ ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
{
struct ahc_softc *ahc;
struct ahc_linux_device *dev = scsi_transport_device_data(cmd->device);
+ int rtn = SCSI_MLQUEUE_HOST_BUSY;
+ unsigned long flags;
ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
- /*
- * Save the callback on completion function.
- */
- cmd->scsi_done = scsi_done;
-
- /*
- * Close the race of a command that was in the process of
- * being queued to us just as our simq was frozen. Let
- * DV commands through so long as we are only frozen to
- * perform DV.
- */
- if (ahc->platform_data->qfrozen != 0)
- return SCSI_MLQUEUE_HOST_BUSY;
-
- cmd->result = CAM_REQ_INPROG << 16;
+ ahc_lock(ahc, &flags);
+ if (ahc->platform_data->qfrozen == 0) {
+ cmd->scsi_done = scsi_done;
+ cmd->result = CAM_REQ_INPROG << 16;
+ rtn = ahc_linux_run_command(ahc, dev, cmd);
+ }
+ ahc_unlock(ahc, &flags);
- return ahc_linux_run_command(ahc, dev, cmd);
+ return rtn;
}
static inline struct scsi_target **
@@ -1079,7 +1073,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
*((struct ahc_softc **)host->hostdata) = ahc;
ahc_lock(ahc, &s);
- scsi_assign_lock(host, &ahc->platform_data->spin_lock);
ahc->platform_data->host = host;
host->can_queue = AHC_MAX_QUEUE;
host->cmd_per_lun = 2;
@@ -2111,6 +2104,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
int paused;
int wait;
int disconnected;
+ unsigned long flags;
pending_scb = NULL;
paused = FALSE;
@@ -2125,7 +2119,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
printf(" 0x%x", cmd->cmnd[cdb_byte]);
printf("\n");
- spin_lock_irq(&ahc->platform_data->spin_lock);
+ ahc_lock(ahc, &flags);
/*
* First determine if we currently own this command.
@@ -2357,7 +2351,8 @@ done:
int ret;
ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE;
- spin_unlock_irq(&ahc->platform_data->spin_lock);
+ ahc_unlock(ahc, &flags);
+
init_timer(&timer);
timer.data = (u_long)ahc;
timer.expires = jiffies + (5 * HZ);
@@ -2371,10 +2366,8 @@ done:
printf("Timer Expired\n");
retval = FAILED;
}
- spin_lock_irq(&ahc->platform_data->spin_lock);
- }
-
- spin_unlock_irq(&ahc->platform_data->spin_lock);
+ } else
+ ahc_unlock(ahc, &flags);
return (retval);
}
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 880e2d9..33d56c3 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -6514,7 +6514,7 @@ do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
static void
aic7xxx_init_transinfo(struct aic7xxx_host *p, struct aic_dev_data *aic_dev)
{
- Scsi_Device *sdpnt = aic_dev->SDptr;
+ struct scsi_device *sdpnt = aic_dev->SDptr;
unsigned char tindex;
tindex = sdpnt->id | (sdpnt->channel << 3);
@@ -6581,7 +6581,7 @@ aic7xxx_init_transinfo(struct aic7xxx_host *p, struct aic_dev_data *aic_dev)
* Set up the initial aic_dev struct pointers
*-F*************************************************************************/
static int
-aic7xxx_slave_alloc(Scsi_Device *SDptr)
+aic7xxx_slave_alloc(struct scsi_device *SDptr)
{
struct aic7xxx_host *p = (struct aic7xxx_host *)SDptr->host->hostdata;
struct aic_dev_data *aic_dev;
@@ -6644,7 +6644,7 @@ aic7xxx_slave_alloc(Scsi_Device *SDptr)
* queueing to be [en|dis]abled for a specific adapter.
*-F*************************************************************************/
static void
-aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device)
+aic7xxx_device_queue_depth(struct aic7xxx_host *p, struct scsi_device *device)
{
int tag_enabled = FALSE;
struct aic_dev_data *aic_dev = device->hostdata;
@@ -6734,7 +6734,7 @@ aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device)
* prepare for this device to go away
*-F*************************************************************************/
static void
-aic7xxx_slave_destroy(Scsi_Device *SDptr)
+aic7xxx_slave_destroy(struct scsi_device *SDptr)
{
struct aic_dev_data *aic_dev = SDptr->hostdata;
@@ -6754,7 +6754,7 @@ aic7xxx_slave_destroy(Scsi_Device *SDptr)
* depths, allocate command structs, etc.
*-F*************************************************************************/
static int
-aic7xxx_slave_configure(Scsi_Device *SDptr)
+aic7xxx_slave_configure(struct scsi_device *SDptr)
{
struct aic7xxx_host *p = (struct aic7xxx_host *) SDptr->host->hostdata;
struct aic_dev_data *aic_dev;
@@ -7865,7 +7865,7 @@ detect_maxscb(struct aic7xxx_host *p)
* Register a Adaptec aic7xxx chip SCSI controller with the kernel.
*-F*************************************************************************/
static int
-aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p,
+aic7xxx_register(struct scsi_host_template *template, struct aic7xxx_host *p,
int reset_delay)
{
int i, result;
@@ -8412,7 +8412,7 @@ aic7xxx_chip_reset(struct aic7xxx_host *p)
* and a pointer to a aic7xxx_host struct upon success.
*-F*************************************************************************/
static struct aic7xxx_host *
-aic7xxx_alloc(Scsi_Host_Template *sht, struct aic7xxx_host *temp)
+aic7xxx_alloc(struct scsi_host_template *sht, struct aic7xxx_host *temp)
{
struct aic7xxx_host *p = NULL;
struct Scsi_Host *host;
@@ -8991,7 +8991,7 @@ aic7xxx_configure_bugs(struct aic7xxx_host *p)
* mid-level SCSI code is overhauled.
*-F*************************************************************************/
static int
-aic7xxx_detect(Scsi_Host_Template *template)
+aic7xxx_detect(struct scsi_host_template *template)
{
struct aic7xxx_host *temp_p = NULL;
struct aic7xxx_host *current_p = NULL;
@@ -11161,7 +11161,7 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(AIC7XXX_H_VERSION);
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_info = aic7xxx_proc_info,
.detect = aic7xxx_detect,
.release = aic7xxx_release,
diff --git a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
index dea8446..c0844fa 100644
--- a/drivers/scsi/amiga7xx.c
+++ b/drivers/scsi/amiga7xx.c
@@ -29,7 +29,7 @@
#include "amiga7xx.h"
-static int amiga7xx_register_one(Scsi_Host_Template *tpnt,
+static int amiga7xx_register_one(struct scsi_host_template *tpnt,
unsigned long address)
{
long long options;
@@ -65,7 +65,7 @@ static struct {
{ 0 }
};
-static int __init amiga7xx_zorro_detect(Scsi_Host_Template *tpnt)
+static int __init amiga7xx_zorro_detect(struct scsi_host_template *tpnt)
{
int num = 0, i;
struct zorro_dev *z = NULL;
@@ -89,7 +89,7 @@ static int __init amiga7xx_zorro_detect(Scsi_Host_Template *tpnt)
#endif /* CONFIG_ZORRO */
-int __init amiga7xx_detect(Scsi_Host_Template *tpnt)
+int __init amiga7xx_detect(struct scsi_host_template *tpnt)
{
static unsigned char called = 0;
int num = 0;
@@ -122,7 +122,7 @@ static int amiga7xx_release(struct Scsi_Host *shost)
return 0;
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = "Amiga NCR53c710 SCSI",
.detect = amiga7xx_detect,
.release = amiga7xx_release,
diff --git a/drivers/scsi/amiga7xx.h b/drivers/scsi/amiga7xx.h
index 8cc54a5..1b63759 100644
--- a/drivers/scsi/amiga7xx.h
+++ b/drivers/scsi/amiga7xx.h
@@ -2,7 +2,7 @@
#include <linux/types.h>
-int amiga7xx_detect(Scsi_Host_Template *);
+int amiga7xx_detect(struct scsi_host_template *);
const char *NCR53c7x0_info(void);
int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int NCR53c7xx_abort(Scsi_Cmnd *);
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index be2caec..b7b20c6 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -896,7 +896,7 @@ void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result)
* Notes : this will only be one SG entry or less
*/
static
-void acornscsi_data_updateptr(AS_Host *host, Scsi_Pointer *SCp, unsigned int length)
+void acornscsi_data_updateptr(AS_Host *host, struct scsi_pointer *SCp, unsigned int length)
{
SCp->ptr += length;
SCp->this_residual -= length;
@@ -2862,7 +2862,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
int length, int inout)
{
int pos, begin = 0, devidx;
- Scsi_Device *scd;
+ struct scsi_device *scd;
AS_Host *host;
char *p = buffer;
@@ -2971,7 +2971,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
return pos;
}
-static Scsi_Host_Template acornscsi_template = {
+static struct scsi_host_template acornscsi_template = {
.module = THIS_MODULE,
.proc_info = acornscsi_proc_info,
.name = "AcornSCSI",
diff --git a/drivers/scsi/arm/acornscsi.h b/drivers/scsi/arm/acornscsi.h
index 03881f0..2142290 100644
--- a/drivers/scsi/arm/acornscsi.h
+++ b/drivers/scsi/arm/acornscsi.h
@@ -292,7 +292,7 @@ typedef struct acornscsi_hostdata {
unsigned char tag; /* reconnected tag */
} reconnected;
- Scsi_Pointer SCp; /* current commands data pointer */
+ struct scsi_pointer SCp; /* current commands data pointer */
MsgQueue_t msgs;
diff --git a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c
index 29811f5..804125e 100644
--- a/drivers/scsi/arm/arxescsi.c
+++ b/drivers/scsi/arm/arxescsi.c
@@ -65,7 +65,7 @@ struct arxescsi_info {
* Returns : 0 if we should not set CMD_WITHDMA for transfer info command
*/
static fasdmatype_t
-arxescsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
+arxescsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp,
fasdmadir_t direction, fasdmatype_t min_type)
{
/*
@@ -111,7 +111,7 @@ static void arxescsi_pseudo_dma_write(unsigned char *addr, void __iomem *base)
* transfer - minimum number of bytes we expect to transfer
*/
static void
-arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
+arxescsi_dma_pseudo(struct Scsi_Host *host, struct scsi_pointer *SCp,
fasdmadir_t direction, int transfer)
{
struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata;
@@ -197,7 +197,7 @@ arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
* Params : host - host
* SCpnt - command
*/
-static void arxescsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp)
+static void arxescsi_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp)
{
/*
* no DMA to stop
@@ -261,7 +261,7 @@ arxescsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t off
return pos;
}
-static Scsi_Host_Template arxescsi_template = {
+static struct scsi_host_template arxescsi_template = {
.proc_info = arxescsi_proc_info,
.name = "ARXE SCSI card",
.info = arxescsi_info,
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
index 26498553..81e266b 100644
--- a/drivers/scsi/arm/cumana_1.c
+++ b/drivers/scsi/arm/cumana_1.c
@@ -238,7 +238,7 @@ static void cumanascsi_write(struct Scsi_Host *instance, int reg, int value)
#include "../NCR5380.c"
-static Scsi_Host_Template cumanascsi_template = {
+static struct scsi_host_template cumanascsi_template = {
.module = THIS_MODULE,
.name = "Cumana 16-bit SCSI",
.info = cumanascsi_info,
diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c
index 0ef0644..3a7a46b 100644
--- a/drivers/scsi/arm/cumana_2.c
+++ b/drivers/scsi/arm/cumana_2.c
@@ -157,7 +157,7 @@ cumanascsi_2_intr(int irq, void *dev_id, struct pt_regs *regs)
* Returns : type of transfer to be performed
*/
static fasdmatype_t
-cumanascsi_2_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
+cumanascsi_2_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp,
fasdmadir_t direction, fasdmatype_t min_type)
{
struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
@@ -209,7 +209,7 @@ cumanascsi_2_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
* transfer - minimum number of bytes we expect to transfer
*/
static void
-cumanascsi_2_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
+cumanascsi_2_dma_pseudo(struct Scsi_Host *host, struct scsi_pointer *SCp,
fasdmadir_t direction, int transfer)
{
struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
@@ -283,7 +283,7 @@ cumanascsi_2_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
* SCpnt - command
*/
static void
-cumanascsi_2_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp)
+cumanascsi_2_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp)
{
struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
if (info->info.scsi.dma != NO_DMA) {
@@ -381,7 +381,7 @@ int cumanascsi_2_proc_info (struct Scsi_Host *host, char *buffer, char **start,
return pos;
}
-static Scsi_Host_Template cumanascsi2_template = {
+static struct scsi_host_template cumanascsi2_template = {
.module = THIS_MODULE,
.proc_info = cumanascsi_2_proc_info,
.name = "Cumana SCSI II",
diff --git a/drivers/scsi/arm/ecoscsi.c b/drivers/scsi/arm/ecoscsi.c
index f8a7fdd..6adcccb 100644
--- a/drivers/scsi/arm/ecoscsi.c
+++ b/drivers/scsi/arm/ecoscsi.c
@@ -155,7 +155,7 @@ printk("reading %p len %d\n",addr, len);
#include "../NCR5380.c"
-static Scsi_Host_Template ecoscsi_template = {
+static struct scsi_host_template ecoscsi_template = {
.module = THIS_MODULE,
.name = "Serial Port EcoSCSI NCR5380",
.proc_name = "ecoscsi",
diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
index ce711f1..4d1e8f5 100644
--- a/drivers/scsi/arm/eesox.c
+++ b/drivers/scsi/arm/eesox.c
@@ -158,7 +158,7 @@ eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
* Returns : type of transfer to be performed
*/
static fasdmatype_t
-eesoxscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
+eesoxscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp,
fasdmadir_t direction, fasdmatype_t min_type)
{
struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
@@ -353,7 +353,7 @@ static void eesoxscsi_buffer_out(void *buf, int length, void __iomem *base)
}
static void
-eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
+eesoxscsi_dma_pseudo(struct Scsi_Host *host, struct scsi_pointer *SCp,
fasdmadir_t dir, int transfer_size)
{
struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
@@ -370,7 +370,7 @@ eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
* SCpnt - command
*/
static void
-eesoxscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp)
+eesoxscsi_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp)
{
struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
if (info->info.scsi.dma != NO_DMA)
@@ -499,7 +499,7 @@ static ssize_t eesoxscsi_store_term(struct device *dev, struct device_attribute
static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR,
eesoxscsi_show_term, eesoxscsi_store_term);
-static Scsi_Host_Template eesox_template = {
+static struct scsi_host_template eesox_template = {
.module = THIS_MODULE,
.proc_info = eesoxscsi_proc_info,
.name = "EESOX SCSI",
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index 4772fb3..3e1053f 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -173,7 +173,7 @@ static void fas216_dumpstate(FAS216_Info *info)
fas216_readb(info, REG_CTCH));
}
-static void print_SCp(Scsi_Pointer *SCp, const char *prefix, const char *suffix)
+static void print_SCp(struct scsi_pointer *SCp, const char *prefix, const char *suffix)
{
printk("%sptr %p this_residual 0x%x buffer %p buffers_residual 0x%x%s",
prefix, SCp->ptr, SCp->this_residual, SCp->buffer,
@@ -628,7 +628,7 @@ static void fas216_handlesync(FAS216_Info *info, char *msg)
*/
static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
{
- Scsi_Pointer *SCp = &info->scsi.SCp;
+ struct scsi_pointer *SCp = &info->scsi.SCp;
fas216_checkmagic(info);
@@ -668,7 +668,7 @@ static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
*/
static void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
{
- Scsi_Pointer *SCp = &info->scsi.SCp;
+ struct scsi_pointer *SCp = &info->scsi.SCp;
fas216_checkmagic(info);
@@ -2559,7 +2559,7 @@ int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
{
FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
unsigned long flags;
- Scsi_Device *SDpnt;
+ struct scsi_device *SDpnt;
fas216_checkmagic(info);
fas216_log(info, LOG_ERROR, "resetting bus");
@@ -3000,7 +3000,7 @@ int fas216_print_stats(FAS216_Info *info, char *buffer)
int fas216_print_devices(FAS216_Info *info, char *buffer)
{
struct fas216_device *dev;
- Scsi_Device *scd;
+ struct scsi_device *scd;
char *p = buffer;
p += sprintf(p, "Device/Lun TaggedQ Parity Sync\n");
diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h
index 60a2a12..540914d 100644
--- a/drivers/scsi/arm/fas216.h
+++ b/drivers/scsi/arm/fas216.h
@@ -243,7 +243,7 @@ typedef struct {
unsigned int irq; /* interrupt */
int dma; /* dma channel */
- Scsi_Pointer SCp; /* current commands data pointer */
+ struct scsi_pointer SCp; /* current commands data pointer */
MsgQueue_t msgs; /* message queue for connected device */
@@ -304,9 +304,9 @@ typedef struct {
/* dma */
struct {
fasdmatype_t transfer_type; /* current type of DMA transfer */
- fasdmatype_t (*setup) (struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t direction, fasdmatype_t min_dma);
- void (*pseudo)(struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t direction, int transfer);
- void (*stop) (struct Scsi_Host *host, Scsi_Pointer *SCp);
+ fasdmatype_t (*setup) (struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_dma);
+ void (*pseudo)(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, int transfer);
+ void (*stop) (struct Scsi_Host *host, struct scsi_pointer *SCp);
} dma;
/* miscellaneous */
diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c
index de24bb9..d806b02 100644
--- a/drivers/scsi/arm/oak.c
+++ b/drivers/scsi/arm/oak.c
@@ -111,7 +111,7 @@ printk("reading %p len %d\n", addr, len);
#include "../NCR5380.c"
-static Scsi_Host_Template oakscsi_template = {
+static struct scsi_host_template oakscsi_template = {
.module = THIS_MODULE,
.proc_info = oakscsi_proc_info,
.name = "Oak 16-bit SCSI",
diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
index abda216..3333d7b 100644
--- a/drivers/scsi/arm/powertec.c
+++ b/drivers/scsi/arm/powertec.c
@@ -132,7 +132,7 @@ powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
* Returns : type of transfer to be performed
*/
static fasdmatype_t
-powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
+powertecscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp,
fasdmadir_t direction, fasdmatype_t min_type)
{
struct powertec_info *info = (struct powertec_info *)host->hostdata;
@@ -174,7 +174,7 @@ powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
* SCpnt - command
*/
static void
-powertecscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp)
+powertecscsi_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp)
{
struct powertec_info *info = (struct powertec_info *)host->hostdata;
if (info->info.scsi.dma != NO_DMA)
@@ -293,7 +293,7 @@ powertecscsi_store_term(struct device *dev, struct device_attribute *attr, const
static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR,
powertecscsi_show_term, powertecscsi_store_term);
-static Scsi_Host_Template powertecscsi_template = {
+static struct scsi_host_template powertecscsi_template = {
.module = THIS_MODULE,
.proc_info = powertecscsi_proc_info,
.name = "PowerTec SCSI",
diff --git a/drivers/scsi/arm/scsi.h b/drivers/scsi/arm/scsi.h
index 1993764..6dd544a 100644
--- a/drivers/scsi/arm/scsi.h
+++ b/drivers/scsi/arm/scsi.h
@@ -18,7 +18,7 @@
* The scatter-gather list handling. This contains all
* the yucky stuff that needs to be fixed properly.
*/
-static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int max)
+static inline int copy_SCp_to_sg(struct scatterlist *sg, struct scsi_pointer *SCp, int max)
{
int bufs = SCp->buffers_residual;
@@ -32,7 +32,7 @@ static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int
return bufs + 1;
}
-static inline int next_SCp(Scsi_Pointer *SCp)
+static inline int next_SCp(struct scsi_pointer *SCp)
{
int ret = SCp->buffers_residual;
if (ret) {
@@ -49,7 +49,7 @@ static inline int next_SCp(Scsi_Pointer *SCp)
return ret;
}
-static inline unsigned char get_next_SCp_byte(Scsi_Pointer *SCp)
+static inline unsigned char get_next_SCp_byte(struct scsi_pointer *SCp)
{
char c = *SCp->ptr;
@@ -59,7 +59,7 @@ static inline unsigned char get_next_SCp_byte(Scsi_Pointer *SCp)
return c;
}
-static inline void put_next_SCp_byte(Scsi_Pointer *SCp, unsigned char c)
+static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c)
{
*SCp->ptr = c;
SCp->ptr += 1;
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index a1bd8d9..333d69d 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -50,7 +50,7 @@
#include <linux/libata.h>
#define DRV_NAME "ata_piix"
-#define DRV_VERSION "1.04"
+#define DRV_VERSION "1.05"
enum {
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
@@ -95,7 +95,7 @@ static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
static unsigned int in_module_init = 1;
-static struct pci_device_id piix_pci_tbl[] = {
+static const struct pci_device_id piix_pci_tbl[] = {
#ifdef ATA_ENABLE_PATA
{ 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata },
{ 0x8086, 0x24db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata },
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 2c12be7..2ae31ce 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -255,7 +255,7 @@
*/
static struct Scsi_Host *first_instance = NULL;
-static Scsi_Host_Template *the_template = NULL;
+static struct scsi_host_template *the_template = NULL;
/* Macros ease life... :-) */
#define SETUP_HOSTDATA(in) \
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
index af8adb6..f4c1ca7 100644
--- a/drivers/scsi/atari_scsi.c
+++ b/drivers/scsi/atari_scsi.c
@@ -600,7 +600,7 @@ int atari_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
#endif
-int atari_scsi_detect (Scsi_Host_Template *host)
+int atari_scsi_detect (struct scsi_host_template *host)
{
static int called = 0;
struct Scsi_Host *instance;
@@ -1141,7 +1141,7 @@ static void atari_scsi_falcon_reg_write( unsigned char reg, unsigned char value
#include "atari_NCR5380.c"
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_info = atari_scsi_proc_info,
.name = "Atari native SCSI",
.detect = atari_scsi_detect,
diff --git a/drivers/scsi/atari_scsi.h b/drivers/scsi/atari_scsi.h
index cc12569..f917bdd 100644
--- a/drivers/scsi/atari_scsi.h
+++ b/drivers/scsi/atari_scsi.h
@@ -18,7 +18,7 @@
/* (I_HAVE_OVERRUNS stuff removed) */
#ifndef ASM
-int atari_scsi_detect (Scsi_Host_Template *);
+int atari_scsi_detect (struct scsi_host_template *);
const char *atari_scsi_info (struct Scsi_Host *);
int atari_scsi_reset (Scsi_Cmnd *, unsigned int);
#ifdef MODULE
diff --git a/drivers/scsi/blz1230.c b/drivers/scsi/blz1230.c
index 4cd9fcf..763e409 100644
--- a/drivers/scsi/blz1230.c
+++ b/drivers/scsi/blz1230.c
@@ -94,7 +94,7 @@ static volatile unsigned char cmd_buffer[16];
*/
/***************************************************************** Detection */
-int __init blz1230_esp_detect(Scsi_Host_Template *tpnt)
+int __init blz1230_esp_detect(struct scsi_host_template *tpnt)
{
struct NCR_ESP *esp;
struct zorro_dev *z = NULL;
@@ -328,7 +328,7 @@ int blz1230_esp_release(struct Scsi_Host *instance)
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "esp-blz1230",
.proc_info = esp_proc_info,
.name = "Blizzard1230 SCSI IV",
diff --git a/drivers/scsi/blz2060.c b/drivers/scsi/blz2060.c
index c5221d0..d72d05f 100644
--- a/drivers/scsi/blz2060.c
+++ b/drivers/scsi/blz2060.c
@@ -90,7 +90,7 @@ static volatile unsigned char cmd_buffer[16];
*/
/***************************************************************** Detection */
-int __init blz2060_esp_detect(Scsi_Host_Template *tpnt)
+int __init blz2060_esp_detect(struct scsi_host_template *tpnt)
{
struct NCR_ESP *esp;
struct zorro_dev *z = NULL;
@@ -282,7 +282,7 @@ int blz2060_esp_release(struct Scsi_Host *instance)
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "esp-blz2060",
.proc_info = esp_proc_info,
.name = "Blizzard2060 SCSI",
diff --git a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c
index 130f30f5..2958b8c 100644
--- a/drivers/scsi/bvme6000.c
+++ b/drivers/scsi/bvme6000.c
@@ -23,7 +23,7 @@
#include<linux/stat.h>
-int bvme6000_scsi_detect(Scsi_Host_Template *tpnt)
+int bvme6000_scsi_detect(struct scsi_host_template *tpnt)
{
static unsigned char called = 0;
int clock;
@@ -59,7 +59,7 @@ static int bvme6000_scsi_release(struct Scsi_Host *shost)
return 0;
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = "BVME6000 NCR53c710 SCSI",
.detect = bvme6000_scsi_detect,
.release = bvme6000_scsi_release,
diff --git a/drivers/scsi/bvme6000.h b/drivers/scsi/bvme6000.h
index 49b6bbb..7c9c036 100644
--- a/drivers/scsi/bvme6000.h
+++ b/drivers/scsi/bvme6000.h
@@ -3,7 +3,7 @@
#include <linux/types.h>
-int bvme6000_scsi_detect(Scsi_Host_Template *);
+int bvme6000_scsi_detect(struct scsi_host_template *);
const char *NCR53c7x0_info(void);
int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int NCR53c7xx_abort(Scsi_Cmnd *);
diff --git a/drivers/scsi/cyberstorm.c b/drivers/scsi/cyberstorm.c
index bdbca85d..f9b940e 100644
--- a/drivers/scsi/cyberstorm.c
+++ b/drivers/scsi/cyberstorm.c
@@ -104,7 +104,7 @@ static volatile unsigned char cmd_buffer[16];
*/
/***************************************************************** Detection */
-int __init cyber_esp_detect(Scsi_Host_Template *tpnt)
+int __init cyber_esp_detect(struct scsi_host_template *tpnt)
{
struct NCR_ESP *esp;
struct zorro_dev *z = NULL;
@@ -353,7 +353,7 @@ int cyber_esp_release(struct Scsi_Host *instance)
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "esp-cyberstorm",
.proc_info = esp_proc_info,
.name = "CyberStorm SCSI",
diff --git a/drivers/scsi/cyberstormII.c b/drivers/scsi/cyberstormII.c
index 845d925..a3caabf 100644
--- a/drivers/scsi/cyberstormII.c
+++ b/drivers/scsi/cyberstormII.c
@@ -81,7 +81,7 @@ static volatile unsigned char cmd_buffer[16];
*/
/***************************************************************** Detection */
-int __init cyberII_esp_detect(Scsi_Host_Template *tpnt)
+int __init cyberII_esp_detect(struct scsi_host_template *tpnt)
{
struct NCR_ESP *esp;
struct zorro_dev *z = NULL;
@@ -290,7 +290,7 @@ int cyberII_esp_release(struct Scsi_Host *instance)
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "esp-cyberstormII",
.proc_info = esp_proc_info,
.name = "CyberStorm Mk II SCSI",
diff --git a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c
index 256d6ba..a35ee43 100644
--- a/drivers/scsi/dec_esp.c
+++ b/drivers/scsi/dec_esp.c
@@ -133,7 +133,7 @@ static struct scsi_host_template driver_template = {
#include "scsi_module.c"
/***************************************************************** Detection */
-static int dec_esp_detect(Scsi_Host_Template * tpnt)
+static int dec_esp_detect(struct scsi_host_template * tpnt)
{
struct NCR_ESP *esp;
struct ConfigDev *esp_dev;
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index 489194a..2ad2a89 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -44,7 +44,7 @@ static int adpt_device_reset(struct scsi_cmnd* cmd);
/*
- * Scsi_Host_Template (see hosts.h)
+ * struct scsi_host_template (see hosts.h)
*/
#define DPT_DRIVER_NAME "Adaptec I2O RAID"
diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c
index 897743b..310d2f4 100644
--- a/drivers/scsi/dtc.c
+++ b/drivers/scsi/dtc.c
@@ -199,7 +199,7 @@ static void __init dtc_setup(char *str, int *ints)
#endif
/*
- * Function : int dtc_detect(Scsi_Host_Template * tpnt)
+ * Function : int dtc_detect(struct scsi_host_template * tpnt)
*
* Purpose : detects and initializes DTC 3180/3280 controllers
* that were autoprobed, overridden on the LILO command line,
@@ -211,7 +211,7 @@ static void __init dtc_setup(char *str, int *ints)
*
*/
-static int __init dtc_detect(Scsi_Host_Template * tpnt)
+static int __init dtc_detect(struct scsi_host_template * tpnt)
{
static int current_override = 0, current_base = 0;
struct Scsi_Host *instance;
@@ -471,7 +471,7 @@ static int dtc_release(struct Scsi_Host *shost)
return 0;
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = "DTC 3180/3280 ",
.detect = dtc_detect,
.release = dtc_release,
diff --git a/drivers/scsi/dtc.h b/drivers/scsi/dtc.h
index 277cd01..0b205f8 100644
--- a/drivers/scsi/dtc.h
+++ b/drivers/scsi/dtc.h
@@ -35,7 +35,7 @@
static int dtc_abort(Scsi_Cmnd *);
static int dtc_biosparam(struct scsi_device *, struct block_device *,
sector_t, int*);
-static int dtc_detect(Scsi_Host_Template *);
+static int dtc_detect(struct scsi_host_template *);
static int dtc_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int dtc_bus_reset(Scsi_Cmnd *);
diff --git a/drivers/scsi/fastlane.c b/drivers/scsi/fastlane.c
index ae47612..ccee68b 100644
--- a/drivers/scsi/fastlane.c
+++ b/drivers/scsi/fastlane.c
@@ -125,7 +125,7 @@ static inline void dma_clear(struct NCR_ESP *esp)
}
/***************************************************************** Detection */
-int __init fastlane_esp_detect(Scsi_Host_Template *tpnt)
+int __init fastlane_esp_detect(struct scsi_host_template *tpnt)
{
struct NCR_ESP *esp;
struct zorro_dev *z = NULL;
@@ -398,7 +398,7 @@ int fastlane_esp_release(struct Scsi_Host *instance)
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "esp-fastlane",
.proc_info = esp_proc_info,
.name = "Fastlane SCSI",
diff --git a/drivers/scsi/fcal.c b/drivers/scsi/fcal.c
index a6f120d..0341654 100644
--- a/drivers/scsi/fcal.c
+++ b/drivers/scsi/fcal.c
@@ -70,7 +70,7 @@ static unsigned char target2alpa[] = {
static int fcal_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd);
-int fcal_slave_configure(Scsi_Device *device)
+int fcal_slave_configure(struct scsi_device *device)
{
int depth_to_use;
@@ -89,7 +89,7 @@ int fcal_slave_configure(Scsi_Device *device)
/* Detect all FC Arbitrated Loops attached to the machine.
fc4 module has done all the work for us... */
-int __init fcal_detect(Scsi_Host_Template *tpnt)
+int __init fcal_detect(struct scsi_host_template *tpnt)
{
int nfcals = 0;
fc_channel *fc;
@@ -244,7 +244,7 @@ int fcal_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t of
SPRINTF (" [AL-PA: %02x, Port WWN: %08x%08x, Node WWN: %08x%08x] Not responded to PRLI\n",
alpa, u1[0], u1[1], u2[0], u2[1]);
} else {
- Scsi_Device *scd;
+ struct scsi_device *scd;
shost_for_each_device(scd, host)
if (scd->id == target) {
SPRINTF (" [AL-PA: %02x, Id: %02d, Port WWN: %08x%08x, Node WWN: %08x%08x] ",
@@ -297,7 +297,7 @@ static int fcal_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmn
return 0;
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = "Fibre Channel Arbitrated Loop",
.detect = fcal_detect,
.release = fcal_release,
diff --git a/drivers/scsi/fcal.h b/drivers/scsi/fcal.h
index 21aa32e..7ff2c349 100644
--- a/drivers/scsi/fcal.h
+++ b/drivers/scsi/fcal.h
@@ -20,8 +20,8 @@ struct fcal {
for a particular channel */
#define FCAL_CAN_QUEUE 512
-int fcal_detect(Scsi_Host_Template *);
+int fcal_detect(struct scsi_host_template *);
int fcal_release(struct Scsi_Host *);
-int fcal_slave_configure(Scsi_Device *);
+int fcal_slave_configure(struct scsi_device *);
#endif /* !(_FCAL_H) */
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
index 6d44602..cca485a 100644
--- a/drivers/scsi/fd_mcs.c
+++ b/drivers/scsi/fd_mcs.c
@@ -343,7 +343,7 @@ static void fd_mcs_make_bus_idle(struct Scsi_Host *shpnt)
outb(0x01 | PARITY_MASK, TMC_Cntl_port);
}
-static int fd_mcs_detect(Scsi_Host_Template * tpnt)
+static int fd_mcs_detect(struct scsi_host_template * tpnt)
{
int loop;
struct Scsi_Host *shpnt;
@@ -1343,7 +1343,7 @@ static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev
return 0;
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "fd_mcs",
.proc_info = fd_mcs_proc_info,
.detect = fd_mcs_detect,
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index a3aa729..45756fa 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -285,7 +285,7 @@ static int __init do_DTC3181E_setup(char *str)
* Locks: none
*/
-int __init generic_NCR5380_detect(Scsi_Host_Template * tpnt)
+int __init generic_NCR5380_detect(struct scsi_host_template * tpnt)
{
static int current_override = 0;
int count, i;
@@ -798,7 +798,7 @@ static int generic_NCR5380_proc_info(struct Scsi_Host *scsi_ptr, char *buffer, c
Scsi_Cmnd *ptr;
struct NCR5380_hostdata *hostdata;
#ifdef NCR5380_STATS
- Scsi_Device *dev;
+ struct scsi_device *dev;
extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
#endif
@@ -899,7 +899,7 @@ static int generic_NCR5380_proc_info(struct Scsi_Host *scsi_ptr, char *buffer, c
#undef PRINTP
#undef ANDP
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_info = generic_NCR5380_proc_info,
.name = "Generic NCR5380/NCR53C400 Scsi Driver",
.detect = generic_NCR5380_detect,
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index c8adc5a..656fbe2 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -45,7 +45,7 @@
#ifndef ASM
static int generic_NCR5380_abort(Scsi_Cmnd *);
-static int generic_NCR5380_detect(Scsi_Host_Template *);
+static int generic_NCR5380_detect(struct scsi_host_template *);
static int generic_NCR5380_release_resources(struct Scsi_Host *);
static int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int generic_NCR5380_bus_reset(Scsi_Cmnd *);
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index af68230..a6deb01 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -94,7 +94,7 @@
* Bugfix free_irq()
*
* Revision 1.56 2001/08/09 11:19:39 achim
- * Scsi_Host_Template changes
+ * struct scsi_host_template changes
*
* Revision 1.55 2001/08/09 10:11:28 achim
* Command HOST_UNFREEZE_IO before cache service init.
@@ -4153,7 +4153,7 @@ int __init option_setup(char *str)
return 1;
}
-static int __init gdth_detect(Scsi_Host_Template *shtp)
+static int __init gdth_detect(struct scsi_host_template *shtp)
{
struct Scsi_Host *shp;
gdth_pci_str pcistr[MAXHA];
@@ -5562,7 +5562,7 @@ static void gdth_flush(int hanum)
#else
Scsi_Cmnd *scp;
#endif
- Scsi_Device *sdev;
+ struct scsi_device *sdev;
char cmnd[MAX_COMMAND_SIZE];
memset(cmnd, 0xff, MAX_COMMAND_SIZE);
@@ -5624,10 +5624,10 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
gdth_cmd_str gdtcmd;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
Scsi_Request *srp;
- Scsi_Device *sdev;
+ struct scsi_device *sdev;
#else
Scsi_Cmnd *scp;
- Scsi_Device *sdev;
+ struct scsi_device *sdev;
#endif
char cmnd[MAX_COMMAND_SIZE];
#endif
@@ -5683,7 +5683,7 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
return NOTIFY_OK;
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "gdth",
.proc_info = gdth_proc_info,
.name = "GDT SCSI Disk Array Controller",
diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h
index c0f1e34..cc4882f 100644
--- a/drivers/scsi/gdth.h
+++ b/drivers/scsi/gdth.h
@@ -944,9 +944,9 @@ typedef struct {
ulong dma32_cnt, dma64_cnt; /* statistics: DMA buffer */
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
- Scsi_Device *sdev;
+ struct scsi_device *sdev;
#else
- Scsi_Device sdev;
+ struct scsi_device sdev;
#endif
} gdth_ha_str;
diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
index 1bd02f8..5e8657f 100644
--- a/drivers/scsi/gdth_proc.c
+++ b/drivers/scsi/gdth_proc.c
@@ -54,10 +54,10 @@ static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host,
int ret_val = -EINVAL;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
Scsi_Request *scp;
- Scsi_Device *sdev;
+ struct scsi_device *sdev;
#else
Scsi_Cmnd *scp;
- Scsi_Device *sdev;
+ struct scsi_device *sdev;
#endif
TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum));
@@ -232,10 +232,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
gdth_evt_str *estr;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
Scsi_Request *scp;
- Scsi_Device *sdev;
+ struct scsi_device *sdev;
#else
Scsi_Cmnd *scp;
- Scsi_Device *sdev;
+ struct scsi_device *sdev;
#endif
char hrec[161];
struct timeval tv;
@@ -275,7 +275,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
scp->cmd_len = 12;
scp->use_sg = 0;
#else
- memset(&sdev,0,sizeof(Scsi_Device));
+ memset(&sdev,0,sizeof(struct scsi_device));
memset(&scp, 0,sizeof(Scsi_Cmnd));
sdev.host = scp.host = host;
sdev.id = scp.target = sdev.host->this_id;
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index ab22387..5b15449 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -169,7 +169,7 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
#define CHECK_WD33C93
-int __init gvp11_detect(Scsi_Host_Template *tpnt)
+int __init gvp11_detect(struct scsi_host_template *tpnt)
{
static unsigned char called = 0;
struct Scsi_Host *instance;
@@ -361,7 +361,7 @@ static int gvp11_bus_reset(Scsi_Cmnd *cmd)
#include "gvp11.h"
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "GVP11",
.name = "GVP Series II SCSI",
.detect = gvp11_detect,
diff --git a/drivers/scsi/gvp11.h b/drivers/scsi/gvp11.h
index 5148d9f..575d219d 100644
--- a/drivers/scsi/gvp11.h
+++ b/drivers/scsi/gvp11.h
@@ -11,7 +11,7 @@
#include <linux/types.h>
-int gvp11_detect(Scsi_Host_Template *);
+int gvp11_detect(struct scsi_host_template *);
int gvp11_release(struct Scsi_Host *);
const char *wd33c93_info(void);
int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 8d97999..b60c1b9 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -492,7 +492,7 @@ static char *ibmrate(unsigned int, int);
static int probe_display(int);
static int probe_bus_mode(int);
static int device_exists(int, int, int *, int *);
-static struct Scsi_Host *ibmmca_register(Scsi_Host_Template *, int, int, int, char *);
+static struct Scsi_Host *ibmmca_register(struct scsi_host_template *, int, int, int, char *);
static int option_setup(char *);
/* local functions needed for proc_info */
static int ldn_access_load(int, int);
@@ -1483,7 +1483,7 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id)
return len;
}
-int ibmmca_detect(Scsi_Host_Template * scsi_template)
+int ibmmca_detect(struct scsi_host_template * scsi_template)
{
struct Scsi_Host *shpnt;
int port, id, i, j, k, list_size, slot;
@@ -1736,7 +1736,7 @@ int ibmmca_detect(Scsi_Host_Template * scsi_template)
return found; /* return the number of found SCSI hosts. Should be 1 or 0. */
}
-static struct Scsi_Host *ibmmca_register(Scsi_Host_Template * scsi_template, int port, int id, int adaptertype, char *hostname)
+static struct Scsi_Host *ibmmca_register(struct scsi_host_template * scsi_template, int port, int id, int adaptertype, char *hostname)
{
struct Scsi_Host *shpnt;
int i, j;
@@ -2494,7 +2494,7 @@ static int option_setup(char *str)
__setup("ibmmcascsi=", option_setup);
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "ibmmca",
.proc_info = ibmmca_proc_info,
.name = "IBM SCSI-Subsystem",
diff --git a/drivers/scsi/ibmmca.h b/drivers/scsi/ibmmca.h
index 6d68f60..017ee2f 100644
--- a/drivers/scsi/ibmmca.h
+++ b/drivers/scsi/ibmmca.h
@@ -11,7 +11,7 @@
/* Common forward declarations for all Linux-versions: */
/* Interfaces to the midlevel Linux SCSI driver */
-static int ibmmca_detect (Scsi_Host_Template *);
+static int ibmmca_detect (struct scsi_host_template *);
static int ibmmca_release (struct Scsi_Host *);
static int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
static int ibmmca_abort (Scsi_Cmnd *);
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 3553da0..e1960d6 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -882,7 +882,7 @@ static inline int should_transform(ide_drive_t *drive, struct scsi_cmnd *cmd)
struct gendisk *disk = cmd->request->rq_disk;
if (disk) {
- struct Scsi_Device_Template **p = disk->private_data;
+ struct struct scsi_device_Template **p = disk->private_data;
if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0)
return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
}
diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
index fe387b5..34daa3e 100644
--- a/drivers/scsi/in2000.c
+++ b/drivers/scsi/in2000.c
@@ -1899,7 +1899,7 @@ static int int_tab[] in2000__INITDATA = {
};
-static int __init in2000_detect(Scsi_Host_Template * tpnt)
+static int __init in2000_detect(struct scsi_host_template * tpnt)
{
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
@@ -2305,7 +2305,7 @@ static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start,
MODULE_LICENSE("GPL");
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "in2000",
.proc_info = in2000_proc_info,
.name = "Always IN2000",
diff --git a/drivers/scsi/in2000.h b/drivers/scsi/in2000.h
index a240b52..0fb8b06 100644
--- a/drivers/scsi/in2000.h
+++ b/drivers/scsi/in2000.h
@@ -395,7 +395,7 @@ struct IN2000_hostdata {
# define CLISPIN_UNLOCK(host,flags) spin_unlock_irqrestore(host->host_lock, \
flags)
-static int in2000_detect(Scsi_Host_Template *) in2000__INIT;
+static int in2000_detect(struct scsi_host_template *) in2000__INIT;
static int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int in2000_abort(Scsi_Cmnd *);
static void in2000_setup(char *, int *) in2000__INIT;
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index e0039df..fa2cb358 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -91,11 +91,14 @@ static unsigned int ipr_max_speed = 1;
static int ipr_testmode = 0;
static unsigned int ipr_fastfail = 0;
static unsigned int ipr_transop_timeout = IPR_OPERATIONAL_TIMEOUT;
+static unsigned int ipr_enable_cache = 1;
+static unsigned int ipr_debug = 0;
+static int ipr_auto_create = 1;
static DEFINE_SPINLOCK(ipr_driver_lock);
/* This table describes the differences between DMA controller chips */
static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
- { /* Gemstone and Citrine */
+ { /* Gemstone, Citrine, and Obsidian */
.mailbox = 0x0042C,
.cache_line_size = 0x20,
{
@@ -130,6 +133,8 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
static const struct ipr_chip_t ipr_chip[] = {
{ PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, &ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, &ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, &ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, &ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, &ipr_chip_cfg[1] },
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, &ipr_chip_cfg[1] }
};
@@ -150,6 +155,12 @@ module_param_named(fastfail, ipr_fastfail, int, 0);
MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries");
module_param_named(transop_timeout, ipr_transop_timeout, int, 0);
MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)");
+module_param_named(enable_cache, ipr_enable_cache, int, 0);
+MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)");
+module_param_named(debug, ipr_debug, int, 0);
+MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)");
+module_param_named(auto_create, ipr_auto_create, int, 0);
+MODULE_PARM_DESC(auto_create, "Auto-create single device RAID 0 arrays when initialized (default: 1)");
MODULE_LICENSE("GPL");
MODULE_VERSION(IPR_DRIVER_VERSION);
@@ -285,12 +296,18 @@ struct ipr_error_table_t ipr_error_table[] = {
"3110: Device bus error, message or command phase"},
{0x04670400, 0, 1,
"9091: Incorrect hardware configuration change has been detected"},
+ {0x04678000, 0, 1,
+ "9073: Invalid multi-adapter configuration"},
{0x046E0000, 0, 1,
"FFF4: Command to logical unit failed"},
{0x05240000, 1, 0,
"Illegal request, invalid request type or request packet"},
{0x05250000, 0, 0,
"Illegal request, invalid resource handle"},
+ {0x05258000, 0, 0,
+ "Illegal request, commands not allowed to this device"},
+ {0x05258100, 0, 0,
+ "Illegal request, command not allowed to a secondary adapter"},
{0x05260000, 0, 0,
"Illegal request, invalid field in parameter list"},
{0x05260100, 0, 0,
@@ -299,6 +316,8 @@ struct ipr_error_table_t ipr_error_table[] = {
"Illegal request, parameter value invalid"},
{0x052C0000, 0, 0,
"Illegal request, command sequence error"},
+ {0x052C8000, 1, 0,
+ "Illegal request, dual adapter support not enabled"},
{0x06040500, 0, 1,
"9031: Array protection temporarily suspended, protection resuming"},
{0x06040600, 0, 1,
@@ -315,18 +334,26 @@ struct ipr_error_table_t ipr_error_table[] = {
"3029: A device replacement has occurred"},
{0x064C8000, 0, 1,
"9051: IOA cache data exists for a missing or failed device"},
+ {0x064C8100, 0, 1,
+ "9055: Auxiliary cache IOA contains cache data needed by the primary IOA"},
{0x06670100, 0, 1,
"9025: Disk unit is not supported at its physical location"},
{0x06670600, 0, 1,
"3020: IOA detected a SCSI bus configuration error"},
{0x06678000, 0, 1,
"3150: SCSI bus configuration error"},
+ {0x06678100, 0, 1,
+ "9074: Asymmetric advanced function disk configuration"},
{0x06690200, 0, 1,
"9041: Array protection temporarily suspended"},
{0x06698200, 0, 1,
"9042: Corrupt array parity detected on specified device"},
{0x066B0200, 0, 1,
"9030: Array no longer protected due to missing or failed disk unit"},
+ {0x066B8000, 0, 1,
+ "9071: Link operational transition"},
+ {0x066B8100, 0, 1,
+ "9072: Link not operational transition"},
{0x066B8200, 0, 1,
"9032: Array exposed but still protected"},
{0x07270000, 0, 0,
@@ -789,7 +816,7 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type,
**/
static void ipr_init_res_entry(struct ipr_resource_entry *res)
{
- res->needs_sync_complete = 1;
+ res->needs_sync_complete = 0;
res->in_erp = 0;
res->add_to_ml = 0;
res->del_from_ml = 0;
@@ -889,29 +916,74 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd)
/**
* ipr_log_vpd - Log the passed VPD to the error log.
- * @vpids: vendor/product id struct
- * @serial_num: serial number string
+ * @vpd: vendor/product id/sn struct
*
* Return value:
* none
**/
-static void ipr_log_vpd(struct ipr_std_inq_vpids *vpids, u8 *serial_num)
+static void ipr_log_vpd(struct ipr_vpd *vpd)
{
char buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN
+ IPR_SERIAL_NUM_LEN];
- memcpy(buffer, vpids->vendor_id, IPR_VENDOR_ID_LEN);
- memcpy(buffer + IPR_VENDOR_ID_LEN, vpids->product_id,
+ memcpy(buffer, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN);
+ memcpy(buffer + IPR_VENDOR_ID_LEN, vpd->vpids.product_id,
IPR_PROD_ID_LEN);
buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN] = '\0';
ipr_err("Vendor/Product ID: %s\n", buffer);
- memcpy(buffer, serial_num, IPR_SERIAL_NUM_LEN);
+ memcpy(buffer, vpd->sn, IPR_SERIAL_NUM_LEN);
buffer[IPR_SERIAL_NUM_LEN] = '\0';
ipr_err(" Serial Number: %s\n", buffer);
}
/**
+ * ipr_log_ext_vpd - Log the passed extended VPD to the error log.
+ * @vpd: vendor/product id/sn/wwn struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd)
+{
+ ipr_log_vpd(&vpd->vpd);
+ ipr_err(" WWN: %08X%08X\n", be32_to_cpu(vpd->wwid[0]),
+ be32_to_cpu(vpd->wwid[1]));
+}
+
+/**
+ * ipr_log_enhanced_cache_error - Log a cache error.
+ * @ioa_cfg: ioa config struct
+ * @hostrcb: hostrcb struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_hostrcb *hostrcb)
+{
+ struct ipr_hostrcb_type_12_error *error =
+ &hostrcb->hcam.u.error.u.type_12_error;
+
+ ipr_err("-----Current Configuration-----\n");
+ ipr_err("Cache Directory Card Information:\n");
+ ipr_log_ext_vpd(&error->ioa_vpd);
+ ipr_err("Adapter Card Information:\n");
+ ipr_log_ext_vpd(&error->cfc_vpd);
+
+ ipr_err("-----Expected Configuration-----\n");
+ ipr_err("Cache Directory Card Information:\n");
+ ipr_log_ext_vpd(&error->ioa_last_attached_to_cfc_vpd);
+ ipr_err("Adapter Card Information:\n");
+ ipr_log_ext_vpd(&error->cfc_last_attached_to_ioa_vpd);
+
+ ipr_err("Additional IOA Data: %08X %08X %08X\n",
+ be32_to_cpu(error->ioa_data[0]),
+ be32_to_cpu(error->ioa_data[1]),
+ be32_to_cpu(error->ioa_data[2]));
+}
+
+/**
* ipr_log_cache_error - Log a cache error.
* @ioa_cfg: ioa config struct
* @hostrcb: hostrcb struct
@@ -927,17 +999,15 @@ static void ipr_log_cache_error(struct ipr_ioa_cfg *ioa_cfg,
ipr_err("-----Current Configuration-----\n");
ipr_err("Cache Directory Card Information:\n");
- ipr_log_vpd(&error->ioa_vpids, error->ioa_sn);
+ ipr_log_vpd(&error->ioa_vpd);
ipr_err("Adapter Card Information:\n");
- ipr_log_vpd(&error->cfc_vpids, error->cfc_sn);
+ ipr_log_vpd(&error->cfc_vpd);
ipr_err("-----Expected Configuration-----\n");
ipr_err("Cache Directory Card Information:\n");
- ipr_log_vpd(&error->ioa_last_attached_to_cfc_vpids,
- error->ioa_last_attached_to_cfc_sn);
+ ipr_log_vpd(&error->ioa_last_attached_to_cfc_vpd);
ipr_err("Adapter Card Information:\n");
- ipr_log_vpd(&error->cfc_last_attached_to_ioa_vpids,
- error->cfc_last_attached_to_ioa_sn);
+ ipr_log_vpd(&error->cfc_last_attached_to_ioa_vpd);
ipr_err("Additional IOA Data: %08X %08X %08X\n",
be32_to_cpu(error->ioa_data[0]),
@@ -946,6 +1016,46 @@ static void ipr_log_cache_error(struct ipr_ioa_cfg *ioa_cfg,
}
/**
+ * ipr_log_enhanced_config_error - Log a configuration error.
+ * @ioa_cfg: ioa config struct
+ * @hostrcb: hostrcb struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_hostrcb *hostrcb)
+{
+ int errors_logged, i;
+ struct ipr_hostrcb_device_data_entry_enhanced *dev_entry;
+ struct ipr_hostrcb_type_13_error *error;
+
+ error = &hostrcb->hcam.u.error.u.type_13_error;
+ errors_logged = be32_to_cpu(error->errors_logged);
+
+ ipr_err("Device Errors Detected/Logged: %d/%d\n",
+ be32_to_cpu(error->errors_detected), errors_logged);
+
+ dev_entry = error->dev;
+
+ for (i = 0; i < errors_logged; i++, dev_entry++) {
+ ipr_err_separator;
+
+ ipr_phys_res_err(ioa_cfg, dev_entry->dev_res_addr, "Device %d", i + 1);
+ ipr_log_ext_vpd(&dev_entry->vpd);
+
+ ipr_err("-----New Device Information-----\n");
+ ipr_log_ext_vpd(&dev_entry->new_vpd);
+
+ ipr_err("Cache Directory Card Information:\n");
+ ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd);
+
+ ipr_err("Adapter Card Information:\n");
+ ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd);
+ }
+}
+
+/**
* ipr_log_config_error - Log a configuration error.
* @ioa_cfg: ioa config struct
* @hostrcb: hostrcb struct
@@ -966,30 +1076,22 @@ static void ipr_log_config_error(struct ipr_ioa_cfg *ioa_cfg,
ipr_err("Device Errors Detected/Logged: %d/%d\n",
be32_to_cpu(error->errors_detected), errors_logged);
- dev_entry = error->dev_entry;
+ dev_entry = error->dev;
for (i = 0; i < errors_logged; i++, dev_entry++) {
ipr_err_separator;
- if (dev_entry->dev_res_addr.bus >= IPR_MAX_NUM_BUSES) {
- ipr_err("Device %d: missing\n", i + 1);
- } else {
- ipr_err("Device %d: %d:%d:%d:%d\n", i + 1,
- ioa_cfg->host->host_no, dev_entry->dev_res_addr.bus,
- dev_entry->dev_res_addr.target, dev_entry->dev_res_addr.lun);
- }
- ipr_log_vpd(&dev_entry->dev_vpids, dev_entry->dev_sn);
+ ipr_phys_res_err(ioa_cfg, dev_entry->dev_res_addr, "Device %d", i + 1);
+ ipr_log_vpd(&dev_entry->vpd);
ipr_err("-----New Device Information-----\n");
- ipr_log_vpd(&dev_entry->new_dev_vpids, dev_entry->new_dev_sn);
+ ipr_log_vpd(&dev_entry->new_vpd);
ipr_err("Cache Directory Card Information:\n");
- ipr_log_vpd(&dev_entry->ioa_last_with_dev_vpids,
- dev_entry->ioa_last_with_dev_sn);
+ ipr_log_vpd(&dev_entry->ioa_last_with_dev_vpd);
ipr_err("Adapter Card Information:\n");
- ipr_log_vpd(&dev_entry->cfc_last_with_dev_vpids,
- dev_entry->cfc_last_with_dev_sn);
+ ipr_log_vpd(&dev_entry->cfc_last_with_dev_vpd);
ipr_err("Additional IOA Data: %08X %08X %08X %08X %08X\n",
be32_to_cpu(dev_entry->ioa_data[0]),
@@ -1001,6 +1103,57 @@ static void ipr_log_config_error(struct ipr_ioa_cfg *ioa_cfg,
}
/**
+ * ipr_log_enhanced_array_error - Log an array configuration error.
+ * @ioa_cfg: ioa config struct
+ * @hostrcb: hostrcb struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_enhanced_array_error(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_hostrcb *hostrcb)
+{
+ int i, num_entries;
+ struct ipr_hostrcb_type_14_error *error;
+ struct ipr_hostrcb_array_data_entry_enhanced *array_entry;
+ const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' };
+
+ error = &hostrcb->hcam.u.error.u.type_14_error;
+
+ ipr_err_separator;
+
+ ipr_err("RAID %s Array Configuration: %d:%d:%d:%d\n",
+ error->protection_level,
+ ioa_cfg->host->host_no,
+ error->last_func_vset_res_addr.bus,
+ error->last_func_vset_res_addr.target,
+ error->last_func_vset_res_addr.lun);
+
+ ipr_err_separator;
+
+ array_entry = error->array_member;
+ num_entries = min_t(u32, be32_to_cpu(error->num_entries),
+ sizeof(error->array_member));
+
+ for (i = 0; i < num_entries; i++, array_entry++) {
+ if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN))
+ continue;
+
+ if (be32_to_cpu(error->exposed_mode_adn) == i)
+ ipr_err("Exposed Array Member %d:\n", i);
+ else
+ ipr_err("Array Member %d:\n", i);
+
+ ipr_log_ext_vpd(&array_entry->vpd);
+ ipr_phys_res_err(ioa_cfg, array_entry->dev_res_addr, "Current Location");
+ ipr_phys_res_err(ioa_cfg, array_entry->expected_dev_res_addr,
+ "Expected Location");
+
+ ipr_err_separator;
+ }
+}
+
+/**
* ipr_log_array_error - Log an array configuration error.
* @ioa_cfg: ioa config struct
* @hostrcb: hostrcb struct
@@ -1032,36 +1185,19 @@ static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg,
array_entry = error->array_member;
for (i = 0; i < 18; i++) {
- if (!memcmp(array_entry->serial_num, zero_sn, IPR_SERIAL_NUM_LEN))
+ if (!memcmp(array_entry->vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN))
continue;
- if (be32_to_cpu(error->exposed_mode_adn) == i) {
+ if (be32_to_cpu(error->exposed_mode_adn) == i)
ipr_err("Exposed Array Member %d:\n", i);
- } else {
+ else
ipr_err("Array Member %d:\n", i);
- }
- ipr_log_vpd(&array_entry->vpids, array_entry->serial_num);
-
- if (array_entry->dev_res_addr.bus >= IPR_MAX_NUM_BUSES) {
- ipr_err("Current Location: unknown\n");
- } else {
- ipr_err("Current Location: %d:%d:%d:%d\n",
- ioa_cfg->host->host_no,
- array_entry->dev_res_addr.bus,
- array_entry->dev_res_addr.target,
- array_entry->dev_res_addr.lun);
- }
+ ipr_log_vpd(&array_entry->vpd);
- if (array_entry->expected_dev_res_addr.bus >= IPR_MAX_NUM_BUSES) {
- ipr_err("Expected Location: unknown\n");
- } else {
- ipr_err("Expected Location: %d:%d:%d:%d\n",
- ioa_cfg->host->host_no,
- array_entry->expected_dev_res_addr.bus,
- array_entry->expected_dev_res_addr.target,
- array_entry->expected_dev_res_addr.lun);
- }
+ ipr_phys_res_err(ioa_cfg, array_entry->dev_res_addr, "Current Location");
+ ipr_phys_res_err(ioa_cfg, array_entry->expected_dev_res_addr,
+ "Expected Location");
ipr_err_separator;
@@ -1073,35 +1209,95 @@ static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg,
}
/**
- * ipr_log_generic_error - Log an adapter error.
- * @ioa_cfg: ioa config struct
- * @hostrcb: hostrcb struct
+ * ipr_log_hex_data - Log additional hex IOA error data.
+ * @data: IOA error data
+ * @len: data length
*
* Return value:
* none
**/
-static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg,
- struct ipr_hostrcb *hostrcb)
+static void ipr_log_hex_data(u32 *data, int len)
{
int i;
- int ioa_data_len = be32_to_cpu(hostrcb->hcam.length);
- if (ioa_data_len == 0)
+ if (len == 0)
return;
- ipr_err("IOA Error Data:\n");
- ipr_err("Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
-
- for (i = 0; i < ioa_data_len / 4; i += 4) {
+ for (i = 0; i < len / 4; i += 4) {
ipr_err("%08X: %08X %08X %08X %08X\n", i*4,
- be32_to_cpu(hostrcb->hcam.u.raw.data[i]),
- be32_to_cpu(hostrcb->hcam.u.raw.data[i+1]),
- be32_to_cpu(hostrcb->hcam.u.raw.data[i+2]),
- be32_to_cpu(hostrcb->hcam.u.raw.data[i+3]));
+ be32_to_cpu(data[i]),
+ be32_to_cpu(data[i+1]),
+ be32_to_cpu(data[i+2]),
+ be32_to_cpu(data[i+3]));
}
}
/**
+ * ipr_log_enhanced_dual_ioa_error - Log an enhanced dual adapter error.
+ * @ioa_cfg: ioa config struct
+ * @hostrcb: hostrcb struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_hostrcb *hostrcb)
+{
+ struct ipr_hostrcb_type_17_error *error;
+
+ error = &hostrcb->hcam.u.error.u.type_17_error;
+ error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
+
+ ipr_err("%s\n", error->failure_reason);
+ ipr_err("Remote Adapter VPD:\n");
+ ipr_log_ext_vpd(&error->vpd);
+ ipr_log_hex_data(error->data,
+ be32_to_cpu(hostrcb->hcam.length) -
+ (offsetof(struct ipr_hostrcb_error, u) +
+ offsetof(struct ipr_hostrcb_type_17_error, data)));
+}
+
+/**
+ * ipr_log_dual_ioa_error - Log a dual adapter error.
+ * @ioa_cfg: ioa config struct
+ * @hostrcb: hostrcb struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_hostrcb *hostrcb)
+{
+ struct ipr_hostrcb_type_07_error *error;
+
+ error = &hostrcb->hcam.u.error.u.type_07_error;
+ error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
+
+ ipr_err("%s\n", error->failure_reason);
+ ipr_err("Remote Adapter VPD:\n");
+ ipr_log_vpd(&error->vpd);
+ ipr_log_hex_data(error->data,
+ be32_to_cpu(hostrcb->hcam.length) -
+ (offsetof(struct ipr_hostrcb_error, u) +
+ offsetof(struct ipr_hostrcb_type_07_error, data)));
+}
+
+/**
+ * ipr_log_generic_error - Log an adapter error.
+ * @ioa_cfg: ioa config struct
+ * @hostrcb: hostrcb struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_hostrcb *hostrcb)
+{
+ ipr_log_hex_data(hostrcb->hcam.u.raw.data,
+ be32_to_cpu(hostrcb->hcam.length));
+}
+
+/**
* ipr_get_error - Find the specfied IOASC in the ipr_error_table.
* @ioasc: IOASC
*
@@ -1172,11 +1368,10 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
if (ioa_cfg->log_level < IPR_DEFAULT_LOG_LEVEL)
return;
+ if (be32_to_cpu(hostrcb->hcam.length) > sizeof(hostrcb->hcam.u.raw))
+ hostrcb->hcam.length = cpu_to_be32(sizeof(hostrcb->hcam.u.raw));
switch (hostrcb->hcam.overlay_id) {
- case IPR_HOST_RCB_OVERLAY_ID_1:
- ipr_log_generic_error(ioa_cfg, hostrcb);
- break;
case IPR_HOST_RCB_OVERLAY_ID_2:
ipr_log_cache_error(ioa_cfg, hostrcb);
break;
@@ -1187,13 +1382,26 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
case IPR_HOST_RCB_OVERLAY_ID_6:
ipr_log_array_error(ioa_cfg, hostrcb);
break;
- case IPR_HOST_RCB_OVERLAY_ID_DEFAULT:
- ipr_log_generic_error(ioa_cfg, hostrcb);
+ case IPR_HOST_RCB_OVERLAY_ID_7:
+ ipr_log_dual_ioa_error(ioa_cfg, hostrcb);
+ break;
+ case IPR_HOST_RCB_OVERLAY_ID_12:
+ ipr_log_enhanced_cache_error(ioa_cfg, hostrcb);
+ break;
+ case IPR_HOST_RCB_OVERLAY_ID_13:
+ ipr_log_enhanced_config_error(ioa_cfg, hostrcb);
+ break;
+ case IPR_HOST_RCB_OVERLAY_ID_14:
+ case IPR_HOST_RCB_OVERLAY_ID_16:
+ ipr_log_enhanced_array_error(ioa_cfg, hostrcb);
break;
+ case IPR_HOST_RCB_OVERLAY_ID_17:
+ ipr_log_enhanced_dual_ioa_error(ioa_cfg, hostrcb);
+ break;
+ case IPR_HOST_RCB_OVERLAY_ID_1:
+ case IPR_HOST_RCB_OVERLAY_ID_DEFAULT:
default:
- dev_err(&ioa_cfg->pdev->dev,
- "Unknown error received. Overlay ID: %d\n",
- hostrcb->hcam.overlay_id);
+ ipr_log_generic_error(ioa_cfg, hostrcb);
break;
}
}
@@ -1972,6 +2180,103 @@ static struct bin_attribute ipr_trace_attr = {
};
#endif
+static const struct {
+ enum ipr_cache_state state;
+ char *name;
+} cache_state [] = {
+ { CACHE_NONE, "none" },
+ { CACHE_DISABLED, "disabled" },
+ { CACHE_ENABLED, "enabled" }
+};
+
+/**
+ * ipr_show_write_caching - Show the write caching attribute
+ * @class_dev: class device struct
+ * @buf: buffer
+ *
+ * Return value:
+ * number of bytes printed to buffer
+ **/
+static ssize_t ipr_show_write_caching(struct class_device *class_dev, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(class_dev);
+ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
+ unsigned long lock_flags = 0;
+ int i, len = 0;
+
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+ for (i = 0; i < ARRAY_SIZE(cache_state); i++) {
+ if (cache_state[i].state == ioa_cfg->cache_state) {
+ len = snprintf(buf, PAGE_SIZE, "%s\n", cache_state[i].name);
+ break;
+ }
+ }
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ return len;
+}
+
+
+/**
+ * ipr_store_write_caching - Enable/disable adapter write cache
+ * @class_dev: class_device struct
+ * @buf: buffer
+ * @count: buffer size
+ *
+ * This function will enable/disable adapter write cache.
+ *
+ * Return value:
+ * count on success / other on failure
+ **/
+static ssize_t ipr_store_write_caching(struct class_device *class_dev,
+ const char *buf, size_t count)
+{
+ struct Scsi_Host *shost = class_to_shost(class_dev);
+ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
+ unsigned long lock_flags = 0;
+ enum ipr_cache_state new_state = CACHE_INVALID;
+ int i;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ if (ioa_cfg->cache_state == CACHE_NONE)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(cache_state); i++) {
+ if (!strncmp(cache_state[i].name, buf, strlen(cache_state[i].name))) {
+ new_state = cache_state[i].state;
+ break;
+ }
+ }
+
+ if (new_state != CACHE_DISABLED && new_state != CACHE_ENABLED)
+ return -EINVAL;
+
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+ if (ioa_cfg->cache_state == new_state) {
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ return count;
+ }
+
+ ioa_cfg->cache_state = new_state;
+ dev_info(&ioa_cfg->pdev->dev, "%s adapter write cache.\n",
+ new_state == CACHE_ENABLED ? "Enabling" : "Disabling");
+ if (!ioa_cfg->in_reset_reload)
+ ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL);
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
+
+ return count;
+}
+
+static struct class_device_attribute ipr_ioa_cache_attr = {
+ .attr = {
+ .name = "write_cache",
+ .mode = S_IRUGO | S_IWUSR,
+ },
+ .show = ipr_show_write_caching,
+ .store = ipr_store_write_caching
+};
+
/**
* ipr_show_fw_version - Show the firmware version
* @class_dev: class device struct
@@ -2112,6 +2417,74 @@ static struct class_device_attribute ipr_diagnostics_attr = {
};
/**
+ * ipr_show_adapter_state - Show the adapter's state
+ * @class_dev: class device struct
+ * @buf: buffer
+ *
+ * Return value:
+ * number of bytes printed to buffer
+ **/
+static ssize_t ipr_show_adapter_state(struct class_device *class_dev, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(class_dev);
+ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
+ unsigned long lock_flags = 0;
+ int len;
+
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+ if (ioa_cfg->ioa_is_dead)
+ len = snprintf(buf, PAGE_SIZE, "offline\n");
+ else
+ len = snprintf(buf, PAGE_SIZE, "online\n");
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ return len;
+}
+
+/**
+ * ipr_store_adapter_state - Change adapter state
+ * @class_dev: class_device struct
+ * @buf: buffer
+ * @count: buffer size
+ *
+ * This function will change the adapter's state.
+ *
+ * Return value:
+ * count on success / other on failure
+ **/
+static ssize_t ipr_store_adapter_state(struct class_device *class_dev,
+ const char *buf, size_t count)
+{
+ struct Scsi_Host *shost = class_to_shost(class_dev);
+ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
+ unsigned long lock_flags;
+ int result = count;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+ if (ioa_cfg->ioa_is_dead && !strncmp(buf, "online", 6)) {
+ ioa_cfg->ioa_is_dead = 0;
+ ioa_cfg->reset_retries = 0;
+ ioa_cfg->in_ioa_bringdown = 0;
+ ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
+ }
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
+
+ return result;
+}
+
+static struct class_device_attribute ipr_ioa_state_attr = {
+ .attr = {
+ .name = "state",
+ .mode = S_IRUGO | S_IWUSR,
+ },
+ .show = ipr_show_adapter_state,
+ .store = ipr_store_adapter_state
+};
+
+/**
* ipr_store_reset_adapter - Reset the adapter
* @class_dev: class_device struct
* @buf: buffer
@@ -2183,7 +2556,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
num_elem = buf_len / bsize_elem;
/* Allocate a scatter/gather list for the DMA */
- sglist = kmalloc(sizeof(struct ipr_sglist) +
+ sglist = kzalloc(sizeof(struct ipr_sglist) +
(sizeof(struct scatterlist) * (num_elem - 1)),
GFP_KERNEL);
@@ -2192,9 +2565,6 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
return NULL;
}
- memset(sglist, 0, sizeof(struct ipr_sglist) +
- (sizeof(struct scatterlist) * (num_elem - 1)));
-
scatterlist = sglist->scatterlist;
sglist->order = order;
@@ -2289,31 +2659,24 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
}
/**
- * ipr_map_ucode_buffer - Map a microcode download buffer
+ * ipr_build_ucode_ioadl - Build a microcode download IOADL
* @ipr_cmd: ipr command struct
* @sglist: scatter/gather list
- * @len: total length of download buffer
*
- * Maps a microcode download scatter/gather list for DMA and
- * builds the IOADL.
+ * Builds a microcode download IOA data list (IOADL).
*
- * Return value:
- * 0 on success / -EIO on failure
**/
-static int ipr_map_ucode_buffer(struct ipr_cmnd *ipr_cmd,
- struct ipr_sglist *sglist, int len)
+static void ipr_build_ucode_ioadl(struct ipr_cmnd *ipr_cmd,
+ struct ipr_sglist *sglist)
{
- struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
struct scatterlist *scatterlist = sglist->scatterlist;
int i;
- ipr_cmd->dma_use_sg = pci_map_sg(ioa_cfg->pdev, scatterlist,
- sglist->num_sg, DMA_TO_DEVICE);
-
+ ipr_cmd->dma_use_sg = sglist->num_dma_sg;
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
- ioarcb->write_data_transfer_length = cpu_to_be32(len);
+ ioarcb->write_data_transfer_length = cpu_to_be32(sglist->buffer_len);
ioarcb->write_ioadl_len =
cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
@@ -2324,15 +2687,52 @@ static int ipr_map_ucode_buffer(struct ipr_cmnd *ipr_cmd,
cpu_to_be32(sg_dma_address(&scatterlist[i]));
}
- if (likely(ipr_cmd->dma_use_sg)) {
- ioadl[i-1].flags_and_data_len |=
- cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+ ioadl[i-1].flags_and_data_len |=
+ cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+}
+
+/**
+ * ipr_update_ioa_ucode - Update IOA's microcode
+ * @ioa_cfg: ioa config struct
+ * @sglist: scatter/gather list
+ *
+ * Initiate an adapter reset to update the IOA's microcode
+ *
+ * Return value:
+ * 0 on success / -EIO on failure
+ **/
+static int ipr_update_ioa_ucode(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_sglist *sglist)
+{
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+
+ if (ioa_cfg->ucode_sglist) {
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ dev_err(&ioa_cfg->pdev->dev,
+ "Microcode download already in progress\n");
+ return -EIO;
}
- else {
- dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
+
+ sglist->num_dma_sg = pci_map_sg(ioa_cfg->pdev, sglist->scatterlist,
+ sglist->num_sg, DMA_TO_DEVICE);
+
+ if (!sglist->num_dma_sg) {
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ dev_err(&ioa_cfg->pdev->dev,
+ "Failed to map microcode download buffer!\n");
return -EIO;
}
+ ioa_cfg->ucode_sglist = sglist;
+ ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL);
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
+
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+ ioa_cfg->ucode_sglist = NULL;
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
return 0;
}
@@ -2355,7 +2755,6 @@ static ssize_t ipr_store_update_fw(struct class_device *class_dev,
struct ipr_ucode_image_header *image_hdr;
const struct firmware *fw_entry;
struct ipr_sglist *sglist;
- unsigned long lock_flags;
char fname[100];
char *src;
int len, result, dnld_size;
@@ -2396,35 +2795,17 @@ static ssize_t ipr_store_update_fw(struct class_device *class_dev,
if (result) {
dev_err(&ioa_cfg->pdev->dev,
"Microcode buffer copy to DMA buffer failed\n");
- ipr_free_ucode_buffer(sglist);
- release_firmware(fw_entry);
- return result;
- }
-
- spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
-
- if (ioa_cfg->ucode_sglist) {
- spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
- dev_err(&ioa_cfg->pdev->dev,
- "Microcode download already in progress\n");
- ipr_free_ucode_buffer(sglist);
- release_firmware(fw_entry);
- return -EIO;
+ goto out;
}
- ioa_cfg->ucode_sglist = sglist;
- ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL);
- spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
- wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
-
- spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
- ioa_cfg->ucode_sglist = NULL;
- spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ result = ipr_update_ioa_ucode(ioa_cfg, sglist);
+ if (!result)
+ result = count;
+out:
ipr_free_ucode_buffer(sglist);
release_firmware(fw_entry);
-
- return count;
+ return result;
}
static struct class_device_attribute ipr_update_fw_attr = {
@@ -2439,8 +2820,10 @@ static struct class_device_attribute *ipr_ioa_attrs[] = {
&ipr_fw_version_attr,
&ipr_log_level_attr,
&ipr_diagnostics_attr,
+ &ipr_ioa_state_attr,
&ipr_ioa_reset_attr,
&ipr_update_fw_attr,
+ &ipr_ioa_cache_attr,
NULL,
};
@@ -2548,14 +2931,13 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg)
unsigned long lock_flags = 0;
ENTER;
- dump = kmalloc(sizeof(struct ipr_dump), GFP_KERNEL);
+ dump = kzalloc(sizeof(struct ipr_dump), GFP_KERNEL);
if (!dump) {
ipr_err("Dump memory allocation failed\n");
return -ENOMEM;
}
- memset(dump, 0, sizeof(struct ipr_dump));
kref_init(&dump->kref);
dump->ioa_cfg = ioa_cfg;
@@ -2824,8 +3206,10 @@ static int ipr_slave_configure(struct scsi_device *sdev)
if (res) {
if (ipr_is_af_dasd_device(res))
sdev->type = TYPE_RAID;
- if (ipr_is_af_dasd_device(res) || ipr_is_ioa_resource(res))
+ if (ipr_is_af_dasd_device(res) || ipr_is_ioa_resource(res)) {
sdev->scsi_level = 4;
+ sdev->no_uld_attach = 1;
+ }
if (ipr_is_vset_device(res)) {
sdev->timeout = IPR_VSET_RW_TIMEOUT;
blk_queue_max_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS);
@@ -2848,13 +3232,14 @@ static int ipr_slave_configure(struct scsi_device *sdev)
* handling new commands.
*
* Return value:
- * 0 on success
+ * 0 on success / -ENXIO if device does not exist
**/
static int ipr_slave_alloc(struct scsi_device *sdev)
{
struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) sdev->host->hostdata;
struct ipr_resource_entry *res;
unsigned long lock_flags;
+ int rc = -ENXIO;
sdev->hostdata = NULL;
@@ -2868,14 +3253,16 @@ static int ipr_slave_alloc(struct scsi_device *sdev)
res->add_to_ml = 0;
res->in_erp = 0;
sdev->hostdata = res;
- res->needs_sync_complete = 1;
+ if (!ipr_is_naca_model(res))
+ res->needs_sync_complete = 1;
+ rc = 0;
break;
}
}
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
- return 0;
+ return rc;
}
/**
@@ -2939,7 +3326,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
res = scsi_cmd->device->hostdata;
- if (!res || (!ipr_is_gscsi(res) && !ipr_is_vset_device(res)))
+ if (!res)
return FAILED;
/*
@@ -3131,7 +3518,8 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd)
}
list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
- res->needs_sync_complete = 1;
+ if (!ipr_is_naca_model(res))
+ res->needs_sync_complete = 1;
LEAVE;
return (IPR_IOASC_SENSE_KEY(ioasc) ? FAILED : SUCCESS);
@@ -3435,7 +3823,8 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd)
}
if (res) {
- res->needs_sync_complete = 1;
+ if (!ipr_is_naca_model(res))
+ res->needs_sync_complete = 1;
res->in_erp = 0;
}
ipr_unmap_sglist(ioa_cfg, ipr_cmd);
@@ -3705,6 +4094,30 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd)
}
/**
+ * ipr_get_autosense - Copy autosense data to sense buffer
+ * @ipr_cmd: ipr command struct
+ *
+ * This function copies the autosense buffer to the buffer
+ * in the scsi_cmd, if there is autosense available.
+ *
+ * Return value:
+ * 1 if autosense was available / 0 if not
+ **/
+static int ipr_get_autosense(struct ipr_cmnd *ipr_cmd)
+{
+ struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
+
+ if ((be32_to_cpu(ioasa->ioasc_specific) &
+ (IPR_ADDITIONAL_STATUS_FMT | IPR_AUTOSENSE_VALID)) == 0)
+ return 0;
+
+ memcpy(ipr_cmd->scsi_cmd->sense_buffer, ioasa->auto_sense.data,
+ min_t(u16, be16_to_cpu(ioasa->auto_sense.auto_sense_len),
+ SCSI_SENSE_BUFFERSIZE));
+ return 1;
+}
+
+/**
* ipr_erp_start - Process an error response for a SCSI op
* @ioa_cfg: ioa config struct
* @ipr_cmd: ipr command struct
@@ -3734,14 +4147,19 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
switch (ioasc & IPR_IOASC_IOASC_MASK) {
case IPR_IOASC_ABORTED_CMD_TERM_BY_HOST:
- scsi_cmd->result |= (DID_IMM_RETRY << 16);
+ if (ipr_is_naca_model(res))
+ scsi_cmd->result |= (DID_ABORT << 16);
+ else
+ scsi_cmd->result |= (DID_IMM_RETRY << 16);
break;
case IPR_IOASC_IR_RESOURCE_HANDLE:
+ case IPR_IOASC_IR_NO_CMDS_TO_2ND_IOA:
scsi_cmd->result |= (DID_NO_CONNECT << 16);
break;
case IPR_IOASC_HW_SEL_TIMEOUT:
scsi_cmd->result |= (DID_NO_CONNECT << 16);
- res->needs_sync_complete = 1;
+ if (!ipr_is_naca_model(res))
+ res->needs_sync_complete = 1;
break;
case IPR_IOASC_SYNC_REQUIRED:
if (!res->in_erp)
@@ -3749,6 +4167,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
scsi_cmd->result |= (DID_IMM_RETRY << 16);
break;
case IPR_IOASC_MED_DO_NOT_REALLOC: /* prevent retries */
+ case IPR_IOASA_IR_DUAL_IOA_DISABLED:
scsi_cmd->result |= (DID_PASSTHROUGH << 16);
break;
case IPR_IOASC_BUS_WAS_RESET:
@@ -3760,21 +4179,27 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
if (!res->resetting_device)
scsi_report_bus_reset(ioa_cfg->host, scsi_cmd->device->channel);
scsi_cmd->result |= (DID_ERROR << 16);
- res->needs_sync_complete = 1;
+ if (!ipr_is_naca_model(res))
+ res->needs_sync_complete = 1;
break;
case IPR_IOASC_HW_DEV_BUS_STATUS:
scsi_cmd->result |= IPR_IOASC_SENSE_STATUS(ioasc);
if (IPR_IOASC_SENSE_STATUS(ioasc) == SAM_STAT_CHECK_CONDITION) {
- ipr_erp_cancel_all(ipr_cmd);
- return;
+ if (!ipr_get_autosense(ipr_cmd)) {
+ if (!ipr_is_naca_model(res)) {
+ ipr_erp_cancel_all(ipr_cmd);
+ return;
+ }
+ }
}
- res->needs_sync_complete = 1;
+ if (!ipr_is_naca_model(res))
+ res->needs_sync_complete = 1;
break;
case IPR_IOASC_NR_INIT_CMD_REQUIRED:
break;
default:
scsi_cmd->result |= (DID_ERROR << 16);
- if (!ipr_is_vset_device(res))
+ if (!ipr_is_vset_device(res) && !ipr_is_naca_model(res))
res->needs_sync_complete = 1;
break;
}
@@ -4073,6 +4498,7 @@ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd)
ioa_cfg->in_reset_reload = 0;
ioa_cfg->allow_cmds = 1;
ioa_cfg->reset_cmd = NULL;
+ ioa_cfg->doorbell |= IPR_RUNTIME_RESET;
list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
if (ioa_cfg->allow_ml_add_del && (res->add_to_ml || res->del_from_ml)) {
@@ -4146,7 +4572,7 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd)
ipr_cmd->job_step = ipr_ioa_reset_done;
list_for_each_entry_continue(res, &ioa_cfg->used_res_q, queue) {
- if (!ipr_is_af_dasd_device(res))
+ if (!IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data))
continue;
ipr_cmd->u.res = res;
@@ -4179,6 +4605,36 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd)
}
/**
+ * ipr_setup_write_cache - Disable write cache if needed
+ * @ipr_cmd: ipr command struct
+ *
+ * This function sets up adapters write cache to desired setting
+ *
+ * Return value:
+ * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
+ **/
+static int ipr_setup_write_cache(struct ipr_cmnd *ipr_cmd)
+{
+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+
+ ipr_cmd->job_step = ipr_set_supported_devs;
+ ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
+ struct ipr_resource_entry, queue);
+
+ if (ioa_cfg->cache_state != CACHE_DISABLED)
+ return IPR_RC_JOB_CONTINUE;
+
+ ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
+ ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
+ ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN;
+ ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL;
+
+ ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
+
+ return IPR_RC_JOB_RETURN;
+}
+
+/**
* ipr_get_mode_page - Locate specified mode page
* @mode_pages: mode page buffer
* @page_code: page code to find
@@ -4389,10 +4845,7 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd)
ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages),
length);
- ipr_cmd->job_step = ipr_set_supported_devs;
- ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
- struct ipr_resource_entry, queue);
-
+ ipr_cmd->job_step = ipr_setup_write_cache;
ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
LEAVE;
@@ -4431,6 +4884,51 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd,
}
/**
+ * ipr_reset_cmd_failed - Handle failure of IOA reset command
+ * @ipr_cmd: ipr command struct
+ *
+ * This function handles the failure of an IOA bringup command.
+ *
+ * Return value:
+ * IPR_RC_JOB_RETURN
+ **/
+static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd)
+{
+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+ u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+
+ dev_err(&ioa_cfg->pdev->dev,
+ "0x%02X failed with IOASC: 0x%08X\n",
+ ipr_cmd->ioarcb.cmd_pkt.cdb[0], ioasc);
+
+ ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
+ list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+ return IPR_RC_JOB_RETURN;
+}
+
+/**
+ * ipr_reset_mode_sense_failed - Handle failure of IOAFP mode sense
+ * @ipr_cmd: ipr command struct
+ *
+ * This function handles the failure of a Mode Sense to the IOAFP.
+ * Some adapters do not handle all mode pages.
+ *
+ * Return value:
+ * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
+ **/
+static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd)
+{
+ u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+
+ if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) {
+ ipr_cmd->job_step = ipr_setup_write_cache;
+ return IPR_RC_JOB_CONTINUE;
+ }
+
+ return ipr_reset_cmd_failed(ipr_cmd);
+}
+
+/**
* ipr_ioafp_mode_sense_page28 - Issue Mode Sense Page 28 to IOA
* @ipr_cmd: ipr command struct
*
@@ -4451,6 +4949,7 @@ static int ipr_ioafp_mode_sense_page28(struct ipr_cmnd *ipr_cmd)
sizeof(struct ipr_mode_pages));
ipr_cmd->job_step = ipr_ioafp_mode_select_page28;
+ ipr_cmd->job_step_failed = ipr_reset_mode_sense_failed;
ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
@@ -4612,6 +5111,27 @@ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page,
}
/**
+ * ipr_inquiry_page_supported - Is the given inquiry page supported
+ * @page0: inquiry page 0 buffer
+ * @page: page code.
+ *
+ * This function determines if the specified inquiry page is supported.
+ *
+ * Return value:
+ * 1 if page is supported / 0 if not
+ **/
+static int ipr_inquiry_page_supported(struct ipr_inquiry_page0 *page0, u8 page)
+{
+ int i;
+
+ for (i = 0; i < min_t(u8, page0->len, IPR_INQUIRY_PAGE0_ENTRIES); i++)
+ if (page0->page[i] == page)
+ return 1;
+
+ return 0;
+}
+
+/**
* ipr_ioafp_page3_inquiry - Send a Page 3 Inquiry to the adapter.
* @ipr_cmd: ipr command struct
*
@@ -4624,6 +5144,36 @@ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page,
static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+ struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data;
+
+ ENTER;
+
+ if (!ipr_inquiry_page_supported(page0, 1))
+ ioa_cfg->cache_state = CACHE_NONE;
+
+ ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg;
+
+ ipr_ioafp_inquiry(ipr_cmd, 1, 3,
+ ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, page3_data),
+ sizeof(struct ipr_inquiry_page3));
+
+ LEAVE;
+ return IPR_RC_JOB_RETURN;
+}
+
+/**
+ * ipr_ioafp_page0_inquiry - Send a Page 0 Inquiry to the adapter.
+ * @ipr_cmd: ipr command struct
+ *
+ * This function sends a Page 0 inquiry to the adapter
+ * to retrieve supported inquiry pages.
+ *
+ * Return value:
+ * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
+ **/
+static int ipr_ioafp_page0_inquiry(struct ipr_cmnd *ipr_cmd)
+{
+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
char type[5];
ENTER;
@@ -4633,11 +5183,11 @@ static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd)
type[4] = '\0';
ioa_cfg->type = simple_strtoul((char *)type, NULL, 16);
- ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg;
+ ipr_cmd->job_step = ipr_ioafp_page3_inquiry;
- ipr_ioafp_inquiry(ipr_cmd, 1, 3,
- ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, page3_data),
- sizeof(struct ipr_inquiry_page3));
+ ipr_ioafp_inquiry(ipr_cmd, 1, 0,
+ ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, page0_data),
+ sizeof(struct ipr_inquiry_page0));
LEAVE;
return IPR_RC_JOB_RETURN;
@@ -4657,7 +5207,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd)
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
ENTER;
- ipr_cmd->job_step = ipr_ioafp_page3_inquiry;
+ ipr_cmd->job_step = ipr_ioafp_page0_inquiry;
ipr_ioafp_inquiry(ipr_cmd, 0, 0,
ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, ioa_vpd),
@@ -4815,7 +5365,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd)
}
/* Enable destructive diagnostics on IOA */
- writel(IPR_DOORBELL, ioa_cfg->regs.set_uproc_interrupt_reg);
+ writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg);
writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg);
int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
@@ -5147,12 +5697,7 @@ static int ipr_reset_ucode_download(struct ipr_cmnd *ipr_cmd)
ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8;
ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff;
- if (ipr_map_ucode_buffer(ipr_cmd, sglist, sglist->buffer_len)) {
- dev_err(&ioa_cfg->pdev->dev,
- "Failed to map microcode download buffer\n");
- return IPR_RC_JOB_CONTINUE;
- }
-
+ ipr_build_ucode_ioadl(ipr_cmd, sglist);
ipr_cmd->job_step = ipr_reset_ucode_download_done;
ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
@@ -5217,7 +5762,6 @@ static int ipr_reset_shutdown_ioa(struct ipr_cmnd *ipr_cmd)
static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd)
{
u32 rc, ioasc;
- unsigned long scratch = ipr_cmd->u.scratch;
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
do {
@@ -5233,17 +5777,13 @@ static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd)
}
if (IPR_IOASC_SENSE_KEY(ioasc)) {
- dev_err(&ioa_cfg->pdev->dev,
- "0x%02X failed with IOASC: 0x%08X\n",
- ipr_cmd->ioarcb.cmd_pkt.cdb[0], ioasc);
-
- ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
- list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
- return;
+ rc = ipr_cmd->job_step_failed(ipr_cmd);
+ if (rc == IPR_RC_JOB_RETURN)
+ return;
}
ipr_reinit_ipr_cmnd(ipr_cmd);
- ipr_cmd->u.scratch = scratch;
+ ipr_cmd->job_step_failed = ipr_reset_cmd_failed;
rc = ipr_cmd->job_step(ipr_cmd);
} while(rc == IPR_RC_JOB_CONTINUE);
}
@@ -5517,15 +6057,12 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
int i, rc = -ENOMEM;
ENTER;
- ioa_cfg->res_entries = kmalloc(sizeof(struct ipr_resource_entry) *
+ ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) *
IPR_MAX_PHYSICAL_DEVS, GFP_KERNEL);
if (!ioa_cfg->res_entries)
goto out;
- memset(ioa_cfg->res_entries, 0,
- sizeof(struct ipr_resource_entry) * IPR_MAX_PHYSICAL_DEVS);
-
for (i = 0; i < IPR_MAX_PHYSICAL_DEVS; i++)
list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q);
@@ -5566,15 +6103,12 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
list_add_tail(&ioa_cfg->hostrcb[i]->queue, &ioa_cfg->hostrcb_free_q);
}
- ioa_cfg->trace = kmalloc(sizeof(struct ipr_trace_entry) *
+ ioa_cfg->trace = kzalloc(sizeof(struct ipr_trace_entry) *
IPR_NUM_TRACE_ENTRIES, GFP_KERNEL);
if (!ioa_cfg->trace)
goto out_free_hostrcb_dma;
- memset(ioa_cfg->trace, 0,
- sizeof(struct ipr_trace_entry) * IPR_NUM_TRACE_ENTRIES);
-
rc = 0;
out:
LEAVE;
@@ -5642,6 +6176,9 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
ioa_cfg->host = host;
ioa_cfg->pdev = pdev;
ioa_cfg->log_level = ipr_log_level;
+ ioa_cfg->doorbell = IPR_DOORBELL;
+ if (!ipr_auto_create)
+ ioa_cfg->doorbell |= IPR_RUNTIME_RESET;
sprintf(ioa_cfg->eye_catcher, IPR_EYECATCHER);
sprintf(ioa_cfg->trace_start, IPR_TRACE_START_LABEL);
sprintf(ioa_cfg->ipr_free_label, IPR_FREEQ_LABEL);
@@ -5660,6 +6197,10 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread, ioa_cfg);
init_waitqueue_head(&ioa_cfg->reset_wait_q);
ioa_cfg->sdt_state = INACTIVE;
+ if (ipr_enable_cache)
+ ioa_cfg->cache_state = CACHE_ENABLED;
+ else
+ ioa_cfg->cache_state = CACHE_DISABLED;
ipr_initialize_bus_attr(ioa_cfg);
@@ -6008,6 +6549,7 @@ static int __devinit ipr_probe(struct pci_dev *pdev,
ipr_scan_vsets(ioa_cfg);
scsi_add_device(ioa_cfg->host, IPR_IOA_BUS, IPR_IOA_TARGET, IPR_IOA_LUN);
ioa_cfg->allow_ml_add_del = 1;
+ ioa_cfg->host->max_channel = IPR_VSET_BUS;
schedule_work(&ioa_cfg->work_q);
return 0;
}
@@ -6055,12 +6597,30 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
{ 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, 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_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_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, 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, 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, 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_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_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F,
+ 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] },
{ }
};
MODULE_DEVICE_TABLE(pci, ipr_pci_table);
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 8cf9671..6bec673 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -36,23 +36,8 @@
/*
* Literals
*/
-#define IPR_DRIVER_VERSION "2.0.14"
-#define IPR_DRIVER_DATE "(May 2, 2005)"
-
-/*
- * IPR_DBG_TRACE: Setting this to 1 will turn on some general function tracing
- * resulting in a bunch of extra debugging printks to the console
- *
- * IPR_DEBUG: Setting this to 1 will turn on some error path tracing.
- * Enables the ipr_trace macro.
- */
-#ifdef IPR_DEBUG_ALL
-#define IPR_DEBUG 1
-#define IPR_DBG_TRACE 1
-#else
-#define IPR_DEBUG 0
-#define IPR_DBG_TRACE 0
-#endif
+#define IPR_DRIVER_VERSION "2.1.0"
+#define IPR_DRIVER_DATE "(October 31, 2005)"
/*
* IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -76,6 +61,10 @@
#define IPR_SUBS_DEV_ID_571A 0x02C0
#define IPR_SUBS_DEV_ID_571B 0x02BE
#define IPR_SUBS_DEV_ID_571E 0x02BF
+#define IPR_SUBS_DEV_ID_571F 0x02D5
+#define IPR_SUBS_DEV_ID_572A 0x02C1
+#define IPR_SUBS_DEV_ID_572B 0x02C2
+#define IPR_SUBS_DEV_ID_575B 0x030D
#define IPR_NAME "ipr"
@@ -95,7 +84,10 @@
#define IPR_IOASC_HW_DEV_BUS_STATUS 0x04448500
#define IPR_IOASC_IOASC_MASK 0xFFFFFF00
#define IPR_IOASC_SCSI_STATUS_MASK 0x000000FF
+#define IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT 0x05240000
#define IPR_IOASC_IR_RESOURCE_HANDLE 0x05250000
+#define IPR_IOASC_IR_NO_CMDS_TO_2ND_IOA 0x05258100
+#define IPR_IOASA_IR_DUAL_IOA_DISABLED 0x052C8000
#define IPR_IOASC_BUS_WAS_RESET 0x06290000
#define IPR_IOASC_BUS_WAS_RESET_BY_OTHER 0x06298000
#define IPR_IOASC_ABORTED_CMD_TERM_BY_HOST 0x0B5A0000
@@ -107,14 +99,14 @@
#define IPR_NUM_LOG_HCAMS 2
#define IPR_NUM_CFG_CHG_HCAMS 2
#define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS)
-#define IPR_MAX_NUM_TARGETS_PER_BUS 0x10
+#define IPR_MAX_NUM_TARGETS_PER_BUS 256
#define IPR_MAX_NUM_LUNS_PER_TARGET 256
#define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8
#define IPR_VSET_BUS 0xff
#define IPR_IOA_BUS 0xff
#define IPR_IOA_TARGET 0xff
#define IPR_IOA_LUN 0xff
-#define IPR_MAX_NUM_BUSES 4
+#define IPR_MAX_NUM_BUSES 8
#define IPR_MAX_BUS_TO_SCAN IPR_MAX_NUM_BUSES
#define IPR_NUM_RESET_RELOAD_RETRIES 3
@@ -205,6 +197,7 @@
#define IPR_SDT_FMT2_EXP_ROM_SEL 0x8
#define IPR_FMT2_SDT_READY_TO_USE 0xC4D4E3F2
#define IPR_DOORBELL 0x82800000
+#define IPR_RUNTIME_RESET 0x40000000
#define IPR_PCII_IOA_TRANS_TO_OPER (0x80000000 >> 0)
#define IPR_PCII_IOARCB_XFER_FAILED (0x80000000 >> 3)
@@ -261,6 +254,16 @@ struct ipr_std_inq_vpids {
u8 product_id[IPR_PROD_ID_LEN];
}__attribute__((packed));
+struct ipr_vpd {
+ struct ipr_std_inq_vpids vpids;
+ u8 sn[IPR_SERIAL_NUM_LEN];
+}__attribute__((packed));
+
+struct ipr_ext_vpd {
+ struct ipr_vpd vpd;
+ __be32 wwid[2];
+}__attribute__((packed));
+
struct ipr_std_inq_data {
u8 peri_qual_dev_type;
#define IPR_STD_INQ_PERI_QUAL(peri) ((peri) >> 5)
@@ -304,6 +307,10 @@ struct ipr_config_table_entry {
#define IPR_SUBTYPE_GENERIC_SCSI 1
#define IPR_SUBTYPE_VOLUME_SET 2
+#define IPR_QUEUEING_MODEL(res) ((((res)->cfgte.flags) & 0x70) >> 4)
+#define IPR_QUEUE_FROZEN_MODEL 0
+#define IPR_QUEUE_NACA_MODEL 1
+
struct ipr_res_addr res_addr;
__be32 res_handle;
__be32 reserved4[2];
@@ -410,23 +417,26 @@ struct ipr_ioadl_desc {
struct ipr_ioasa_vset {
__be32 failing_lba_hi;
__be32 failing_lba_lo;
- __be32 ioa_data[22];
+ __be32 reserved;
}__attribute__((packed, aligned (4)));
struct ipr_ioasa_af_dasd {
__be32 failing_lba;
+ __be32 reserved[2];
}__attribute__((packed, aligned (4)));
struct ipr_ioasa_gpdd {
u8 end_state;
u8 bus_phase;
__be16 reserved;
- __be32 ioa_data[23];
+ __be32 ioa_data[2];
}__attribute__((packed, aligned (4)));
-struct ipr_ioasa_raw {
- __be32 ioa_data[24];
-}__attribute__((packed, aligned (4)));
+struct ipr_auto_sense {
+ __be16 auto_sense_len;
+ __be16 ioa_data_len;
+ __be32 data[SCSI_SENSE_BUFFERSIZE/sizeof(__be32)];
+};
struct ipr_ioasa {
__be32 ioasc;
@@ -453,6 +463,8 @@ struct ipr_ioasa {
__be32 fd_res_handle;
__be32 ioasc_specific; /* status code specific field */
+#define IPR_ADDITIONAL_STATUS_FMT 0x80000000
+#define IPR_AUTOSENSE_VALID 0x40000000
#define IPR_IOASC_SPECIFIC_MASK 0x00ffffff
#define IPR_FIELD_POINTER_VALID (0x80000000 >> 8)
#define IPR_FIELD_POINTER_MASK 0x0000ffff
@@ -461,8 +473,9 @@ struct ipr_ioasa {
struct ipr_ioasa_vset vset;
struct ipr_ioasa_af_dasd dasd;
struct ipr_ioasa_gpdd gpdd;
- struct ipr_ioasa_raw raw;
} u;
+
+ struct ipr_auto_sense auto_sense;
}__attribute__((packed, aligned (4)));
struct ipr_mode_parm_hdr {
@@ -536,28 +549,49 @@ struct ipr_inquiry_page3 {
u8 patch_number[4];
}__attribute__((packed));
+#define IPR_INQUIRY_PAGE0_ENTRIES 20
+struct ipr_inquiry_page0 {
+ u8 peri_qual_dev_type;
+ u8 page_code;
+ u8 reserved1;
+ u8 len;
+ u8 page[IPR_INQUIRY_PAGE0_ENTRIES];
+}__attribute__((packed));
+
struct ipr_hostrcb_device_data_entry {
- struct ipr_std_inq_vpids dev_vpids;
- u8 dev_sn[IPR_SERIAL_NUM_LEN];
+ struct ipr_vpd vpd;
struct ipr_res_addr dev_res_addr;
- struct ipr_std_inq_vpids new_dev_vpids;
- u8 new_dev_sn[IPR_SERIAL_NUM_LEN];
- struct ipr_std_inq_vpids ioa_last_with_dev_vpids;
- u8 ioa_last_with_dev_sn[IPR_SERIAL_NUM_LEN];
- struct ipr_std_inq_vpids cfc_last_with_dev_vpids;
- u8 cfc_last_with_dev_sn[IPR_SERIAL_NUM_LEN];
+ struct ipr_vpd new_vpd;
+ struct ipr_vpd ioa_last_with_dev_vpd;
+ struct ipr_vpd cfc_last_with_dev_vpd;
__be32 ioa_data[5];
}__attribute__((packed, aligned (4)));
+struct ipr_hostrcb_device_data_entry_enhanced {
+ struct ipr_ext_vpd vpd;
+ u8 ccin[4];
+ struct ipr_res_addr dev_res_addr;
+ struct ipr_ext_vpd new_vpd;
+ u8 new_ccin[4];
+ struct ipr_ext_vpd ioa_last_with_dev_vpd;
+ struct ipr_ext_vpd cfc_last_with_dev_vpd;
+}__attribute__((packed, aligned (4)));
+
struct ipr_hostrcb_array_data_entry {
- struct ipr_std_inq_vpids vpids;
- u8 serial_num[IPR_SERIAL_NUM_LEN];
+ struct ipr_vpd vpd;
+ struct ipr_res_addr expected_dev_res_addr;
+ struct ipr_res_addr dev_res_addr;
+}__attribute__((packed, aligned (4)));
+
+struct ipr_hostrcb_array_data_entry_enhanced {
+ struct ipr_ext_vpd vpd;
+ u8 ccin[4];
struct ipr_res_addr expected_dev_res_addr;
struct ipr_res_addr dev_res_addr;
}__attribute__((packed, aligned (4)));
struct ipr_hostrcb_type_ff_error {
- __be32 ioa_data[246];
+ __be32 ioa_data[502];
}__attribute__((packed, aligned (4)));
struct ipr_hostrcb_type_01_error {
@@ -568,47 +602,75 @@ struct ipr_hostrcb_type_01_error {
}__attribute__((packed, aligned (4)));
struct ipr_hostrcb_type_02_error {
- struct ipr_std_inq_vpids ioa_vpids;
- u8 ioa_sn[IPR_SERIAL_NUM_LEN];
- struct ipr_std_inq_vpids cfc_vpids;
- u8 cfc_sn[IPR_SERIAL_NUM_LEN];
- struct ipr_std_inq_vpids ioa_last_attached_to_cfc_vpids;
- u8 ioa_last_attached_to_cfc_sn[IPR_SERIAL_NUM_LEN];
- struct ipr_std_inq_vpids cfc_last_attached_to_ioa_vpids;
- u8 cfc_last_attached_to_ioa_sn[IPR_SERIAL_NUM_LEN];
+ struct ipr_vpd ioa_vpd;
+ struct ipr_vpd cfc_vpd;
+ struct ipr_vpd ioa_last_attached_to_cfc_vpd;
+ struct ipr_vpd cfc_last_attached_to_ioa_vpd;
+ __be32 ioa_data[3];
+}__attribute__((packed, aligned (4)));
+
+struct ipr_hostrcb_type_12_error {
+ struct ipr_ext_vpd ioa_vpd;
+ struct ipr_ext_vpd cfc_vpd;
+ struct ipr_ext_vpd ioa_last_attached_to_cfc_vpd;
+ struct ipr_ext_vpd cfc_last_attached_to_ioa_vpd;
__be32 ioa_data[3];
- u8 reserved[844];
}__attribute__((packed, aligned (4)));
struct ipr_hostrcb_type_03_error {
- struct ipr_std_inq_vpids ioa_vpids;
- u8 ioa_sn[IPR_SERIAL_NUM_LEN];
- struct ipr_std_inq_vpids cfc_vpids;
- u8 cfc_sn[IPR_SERIAL_NUM_LEN];
+ struct ipr_vpd ioa_vpd;
+ struct ipr_vpd cfc_vpd;
__be32 errors_detected;
__be32 errors_logged;
u8 ioa_data[12];
- struct ipr_hostrcb_device_data_entry dev_entry[3];
- u8 reserved[444];
+ struct ipr_hostrcb_device_data_entry dev[3];
+}__attribute__((packed, aligned (4)));
+
+struct ipr_hostrcb_type_13_error {
+ struct ipr_ext_vpd ioa_vpd;
+ struct ipr_ext_vpd cfc_vpd;
+ __be32 errors_detected;
+ __be32 errors_logged;
+ struct ipr_hostrcb_device_data_entry_enhanced dev[3];
}__attribute__((packed, aligned (4)));
struct ipr_hostrcb_type_04_error {
- struct ipr_std_inq_vpids ioa_vpids;
- u8 ioa_sn[IPR_SERIAL_NUM_LEN];
- struct ipr_std_inq_vpids cfc_vpids;
- u8 cfc_sn[IPR_SERIAL_NUM_LEN];
+ struct ipr_vpd ioa_vpd;
+ struct ipr_vpd cfc_vpd;
u8 ioa_data[12];
struct ipr_hostrcb_array_data_entry array_member[10];
__be32 exposed_mode_adn;
__be32 array_id;
- struct ipr_std_inq_vpids incomp_dev_vpids;
- u8 incomp_dev_sn[IPR_SERIAL_NUM_LEN];
+ struct ipr_vpd incomp_dev_vpd;
__be32 ioa_data2;
struct ipr_hostrcb_array_data_entry array_member2[8];
struct ipr_res_addr last_func_vset_res_addr;
u8 vset_serial_num[IPR_SERIAL_NUM_LEN];
u8 protection_level[8];
- u8 reserved[124];
+}__attribute__((packed, aligned (4)));
+
+struct ipr_hostrcb_type_14_error {
+ struct ipr_ext_vpd ioa_vpd;
+ struct ipr_ext_vpd cfc_vpd;
+ __be32 exposed_mode_adn;
+ __be32 array_id;
+ struct ipr_res_addr last_func_vset_res_addr;
+ u8 vset_serial_num[IPR_SERIAL_NUM_LEN];
+ u8 protection_level[8];
+ __be32 num_entries;
+ struct ipr_hostrcb_array_data_entry_enhanced array_member[18];
+}__attribute__((packed, aligned (4)));
+
+struct ipr_hostrcb_type_07_error {
+ u8 failure_reason[64];
+ struct ipr_vpd vpd;
+ u32 data[222];
+}__attribute__((packed, aligned (4)));
+
+struct ipr_hostrcb_type_17_error {
+ u8 failure_reason[64];
+ struct ipr_ext_vpd vpd;
+ u32 data[476];
}__attribute__((packed, aligned (4)));
struct ipr_hostrcb_error {
@@ -622,6 +684,11 @@ struct ipr_hostrcb_error {
struct ipr_hostrcb_type_02_error type_02_error;
struct ipr_hostrcb_type_03_error type_03_error;
struct ipr_hostrcb_type_04_error type_04_error;
+ struct ipr_hostrcb_type_07_error type_07_error;
+ struct ipr_hostrcb_type_12_error type_12_error;
+ struct ipr_hostrcb_type_13_error type_13_error;
+ struct ipr_hostrcb_type_14_error type_14_error;
+ struct ipr_hostrcb_type_17_error type_17_error;
} u;
}__attribute__((packed, aligned (4)));
@@ -655,6 +722,12 @@ struct ipr_hcam {
#define IPR_HOST_RCB_OVERLAY_ID_3 0x03
#define IPR_HOST_RCB_OVERLAY_ID_4 0x04
#define IPR_HOST_RCB_OVERLAY_ID_6 0x06
+#define IPR_HOST_RCB_OVERLAY_ID_7 0x07
+#define IPR_HOST_RCB_OVERLAY_ID_12 0x12
+#define IPR_HOST_RCB_OVERLAY_ID_13 0x13
+#define IPR_HOST_RCB_OVERLAY_ID_14 0x14
+#define IPR_HOST_RCB_OVERLAY_ID_16 0x16
+#define IPR_HOST_RCB_OVERLAY_ID_17 0x17
#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF
u8 reserved1[3];
@@ -743,6 +816,7 @@ struct ipr_resource_table {
struct ipr_misc_cbs {
struct ipr_ioa_vpd ioa_vpd;
+ struct ipr_inquiry_page0 page0_data;
struct ipr_inquiry_page3 page3_data;
struct ipr_mode_pages mode_pages;
struct ipr_supported_device supp_dev;
@@ -813,6 +887,7 @@ struct ipr_trace_entry {
struct ipr_sglist {
u32 order;
u32 num_sg;
+ u32 num_dma_sg;
u32 buffer_len;
struct scatterlist scatterlist[1];
};
@@ -825,6 +900,13 @@ enum ipr_sdt_state {
DUMP_OBTAINED
};
+enum ipr_cache_state {
+ CACHE_NONE,
+ CACHE_DISABLED,
+ CACHE_ENABLED,
+ CACHE_INVALID
+};
+
/* Per-controller data */
struct ipr_ioa_cfg {
char eye_catcher[8];
@@ -841,6 +923,7 @@ struct ipr_ioa_cfg {
u8 allow_cmds:1;
u8 allow_ml_add_del:1;
+ enum ipr_cache_state cache_state;
u16 type; /* CCIN of the card */
u8 log_level;
@@ -911,6 +994,7 @@ struct ipr_ioa_cfg {
u16 reset_retries;
u32 errors_logged;
+ u32 doorbell;
struct Scsi_Host *host;
struct pci_dev *pdev;
@@ -948,6 +1032,7 @@ struct ipr_cmnd {
struct timer_list timer;
void (*done) (struct ipr_cmnd *);
int (*job_step) (struct ipr_cmnd *);
+ int (*job_step_failed) (struct ipr_cmnd *);
u16 cmd_index;
u8 sense_buffer[SCSI_SENSE_BUFFERSIZE];
dma_addr_t sense_buffer_dma;
@@ -1083,11 +1168,7 @@ struct ipr_ucode_image_header {
/*
* Macros
*/
-#if IPR_DEBUG
-#define IPR_DBG_CMD(CMD) do { CMD; } while (0)
-#else
-#define IPR_DBG_CMD(CMD)
-#endif
+#define IPR_DBG_CMD(CMD) if (ipr_debug) { CMD; }
#ifdef CONFIG_SCSI_IPR_TRACE
#define ipr_create_trace_file(kobj, attr) sysfs_create_bin_file(kobj, attr)
@@ -1135,16 +1216,22 @@ struct ipr_ucode_image_header {
#define ipr_res_dbg(ioa_cfg, res, fmt, ...) \
IPR_DBG_CMD(ipr_res_printk(KERN_INFO, ioa_cfg, res, fmt, ##__VA_ARGS__))
+#define ipr_phys_res_err(ioa_cfg, res, fmt, ...) \
+{ \
+ if ((res).bus >= IPR_MAX_NUM_BUSES) { \
+ ipr_err(fmt": unknown\n", ##__VA_ARGS__); \
+ } else { \
+ ipr_err(fmt": %d:%d:%d:%d\n", \
+ ##__VA_ARGS__, (ioa_cfg)->host->host_no, \
+ (res).bus, (res).target, (res).lun); \
+ } \
+}
+
#define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\
__FILE__, __FUNCTION__, __LINE__)
-#if IPR_DBG_TRACE
-#define ENTER printk(KERN_INFO IPR_NAME": Entering %s\n", __FUNCTION__)
-#define LEAVE printk(KERN_INFO IPR_NAME": Leaving %s\n", __FUNCTION__)
-#else
-#define ENTER
-#define LEAVE
-#endif
+#define ENTER IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Entering %s\n", __FUNCTION__))
+#define LEAVE IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Leaving %s\n", __FUNCTION__))
#define ipr_err_separator \
ipr_err("----------------------------------------------------------\n")
@@ -1217,6 +1304,20 @@ static inline int ipr_is_gscsi(struct ipr_resource_entry *res)
}
/**
+ * ipr_is_naca_model - Determine if a resource is using NACA queueing model
+ * @res: resource entry struct
+ *
+ * Return value:
+ * 1 if NACA queueing model / 0 if not NACA queueing model
+ **/
+static inline int ipr_is_naca_model(struct ipr_resource_entry *res)
+{
+ if (ipr_is_gscsi(res) && IPR_QUEUEING_MODEL(res) == IPR_QUEUE_NACA_MODEL)
+ return 1;
+ return 0;
+}
+
+/**
* ipr_is_device - Determine if resource address is that of a device
* @res_addr: resource address struct
*
@@ -1226,7 +1327,7 @@ static inline int ipr_is_gscsi(struct ipr_resource_entry *res)
static inline int ipr_is_device(struct ipr_res_addr *res_addr)
{
if ((res_addr->bus < IPR_MAX_NUM_BUSES) &&
- (res_addr->target < IPR_MAX_NUM_TARGETS_PER_BUS))
+ (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1)))
return 1;
return 0;
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index cd9b95d..3882d48 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -139,6 +139,7 @@
/* - Remove 3 unused "inline" functions */
/* 7.12.xx - Use STATIC functions whereever possible */
/* - Clean up deprecated MODULE_PARM calls */
+/* 7.12.05 - Remove Version Matching per IBM request */
/*****************************************************************************/
/*
@@ -210,7 +211,7 @@ module_param(ips, charp, 0);
* DRIVER_VER
*/
#define IPS_VERSION_HIGH "7.12"
-#define IPS_VERSION_LOW ".02 "
+#define IPS_VERSION_LOW ".05 "
#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
@@ -247,7 +248,7 @@ module_param(ips, charp, 0);
/*
* Function prototypes
*/
-static int ips_detect(Scsi_Host_Template *);
+static int ips_detect(struct scsi_host_template *);
static int ips_release(struct Scsi_Host *);
static int ips_eh_abort(Scsi_Cmnd *);
static int ips_eh_reset(Scsi_Cmnd *);
@@ -347,8 +348,6 @@ static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
static int ips_host_info(ips_ha_t *, char *, off_t, int);
static void copy_mem_info(IPS_INFOSTR *, char *, int);
static int copy_info(IPS_INFOSTR *, char *, ...);
-static int ips_get_version_info(ips_ha_t * ha, dma_addr_t, int intr);
-static void ips_version_check(ips_ha_t * ha, int intr);
static int ips_abort_init(ips_ha_t * ha, int index);
static int ips_init_phase2(int index);
@@ -378,7 +377,7 @@ static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */
static dma_addr_t ips_flashbusaddr;
static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */
static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */
-static Scsi_Host_Template ips_driver_template = {
+static struct scsi_host_template ips_driver_template = {
.detect = ips_detect,
.release = ips_release,
.info = ips_info,
@@ -406,8 +405,6 @@ static Scsi_Host_Template ips_driver_template = {
#endif
};
-static IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */
-
/* This table describes all ServeRAID Adapters */
static struct pci_device_id ips_pci_table[] = {
@@ -590,7 +587,7 @@ __setup("ips=", ips_setup);
/* */
/****************************************************************************/
static int
-ips_detect(Scsi_Host_Template * SHT)
+ips_detect(struct scsi_host_template * SHT)
{
int i;
@@ -1265,9 +1262,9 @@ ips_proc24_info(char *buffer, char **start, off_t offset, int length,
/* */
/****************************************************************************/
static void
-ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device * scsi_devs)
+ips_select_queue_depth(struct Scsi_Host *host, struct scsi_device * scsi_devs)
{
- Scsi_Device *device;
+ struct scsi_device *device;
ips_ha_t *ha;
int count = 0;
int min;
@@ -1310,7 +1307,7 @@ ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device * scsi_devs)
/* */
/****************************************************************************/
static int
-ips_slave_configure(Scsi_Device * SDptr)
+ips_slave_configure(struct scsi_device * SDptr)
{
ips_ha_t *ha;
int min;
@@ -5930,7 +5927,7 @@ ips_write_driver_status(ips_ha_t * ha, int intr)
strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4);
strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4);
- ips_version_check(ha, intr); /* Check BIOS/FW/Driver Versions */
+ ha->nvram->versioning = 0; /* Indicate the Driver Does Not Support Versioning */
/* now update the page */
if (!ips_readwrite_page5(ha, TRUE, intr)) {
@@ -6847,135 +6844,6 @@ ips_verify_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize,
return (0);
}
-/*---------------------------------------------------------------------------*/
-/* Routine Name: ips_version_check */
-/* */
-/* Dependencies: */
-/* Assumes that ips_read_adapter_status() is called first filling in */
-/* the data for SubSystem Parameters. */
-/* Called from ips_write_driver_status() so it also assumes NVRAM Page 5 */
-/* Data is available. */
-/* */
-/*---------------------------------------------------------------------------*/
-static void
-ips_version_check(ips_ha_t * ha, int intr)
-{
- IPS_VERSION_DATA *VersionInfo;
- uint8_t FirmwareVersion[IPS_COMPAT_ID_LENGTH + 1];
- uint8_t BiosVersion[IPS_COMPAT_ID_LENGTH + 1];
- int MatchError;
- int rc;
- char BiosString[10];
- char FirmwareString[10];
-
- METHOD_TRACE("ips_version_check", 1);
-
- VersionInfo = ( IPS_VERSION_DATA * ) ha->ioctl_data;
-
- memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
- memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
-
- /* Get the Compatible BIOS Version from NVRAM Page 5 */
- memcpy(BiosVersion, ha->nvram->BiosCompatibilityID,
- IPS_COMPAT_ID_LENGTH);
-
- rc = IPS_FAILURE;
- if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) { /* If Versioning is Supported */
- /* Get the Version Info with a Get Version Command */
- memset( VersionInfo, 0, sizeof (IPS_VERSION_DATA));
- rc = ips_get_version_info(ha, ha->ioctl_busaddr, intr);
- if (rc == IPS_SUCCESS)
- memcpy(FirmwareVersion, VersionInfo->compatibilityId,
- IPS_COMPAT_ID_LENGTH);
- }
-
- if (rc != IPS_SUCCESS) { /* If Data Not Obtainable from a GetVersion Command */
- /* Get the Firmware Version from Enquiry Data */
- memcpy(FirmwareVersion, ha->enq->CodeBlkVersion,
- IPS_COMPAT_ID_LENGTH);
- }
-
- /* printk(KERN_WARNING "Adapter's BIOS Version = %s\n", BiosVersion); */
- /* printk(KERN_WARNING "BIOS Compatible Version = %s\n", IPS_COMPAT_BIOS); */
- /* printk(KERN_WARNING "Adapter's Firmware Version = %s\n", FirmwareVersion); */
- /* printk(KERN_WARNING "Firmware Compatible Version = %s \n", Compatable[ ha->nvram->adapter_type ]); */
-
- MatchError = 0;
-
- if (strncmp
- (FirmwareVersion, Compatable[ha->nvram->adapter_type],
- IPS_COMPAT_ID_LENGTH) != 0)
- MatchError = 1;
-
- if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0)
- MatchError = 1;
-
- ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */
-
- if (MatchError) {
- ha->nvram->version_mismatch = 1;
- if (ips_cd_boot == 0) {
- strncpy(&BiosString[0], ha->nvram->bios_high, 4);
- strncpy(&BiosString[4], ha->nvram->bios_low, 4);
- BiosString[8] = 0;
-
- strncpy(&FirmwareString[0], ha->enq->CodeBlkVersion, 8);
- FirmwareString[8] = 0;
-
- IPS_PRINTK(KERN_WARNING, ha->pcidev,
- "Warning ! ! ! ServeRAID Version Mismatch\n");
- IPS_PRINTK(KERN_WARNING, ha->pcidev,
- "Bios = %s, Firmware = %s, Device Driver = %s%s\n",
- BiosString, FirmwareString, IPS_VERSION_HIGH,
- IPS_VERSION_LOW);
- IPS_PRINTK(KERN_WARNING, ha->pcidev,
- "These levels should match to avoid possible compatibility problems.\n");
- }
- } else {
- ha->nvram->version_mismatch = 0;
- }
-
- return;
-}
-
-/*---------------------------------------------------------------------------*/
-/* Routine Name: ips_get_version_info */
-/* */
-/* Routine Description: */
-/* Issue an internal GETVERSION Command */
-/* */
-/* Return Value: */
-/* 0 if Successful, else non-zero */
-/*---------------------------------------------------------------------------*/
-static int
-ips_get_version_info(ips_ha_t * ha, dma_addr_t Buffer, int intr)
-{
- ips_scb_t *scb;
- int rc;
-
- METHOD_TRACE("ips_get_version_info", 1);
-
- scb = &ha->scbs[ha->max_cmds - 1];
-
- ips_init_scb(ha, scb);
-
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_GET_VERSION_INFO;
- scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO;
- scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.version_info.reserved = 0;
- scb->cmd.version_info.count = sizeof (IPS_VERSION_DATA);
- scb->cmd.version_info.reserved2 = 0;
- scb->data_len = sizeof (IPS_VERSION_DATA);
- scb->data_busaddr = Buffer;
- scb->cmd.version_info.buffer_addr = Buffer;
- scb->flags = 0;
-
- /* issue command */
- rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
- return (rc);
-}
-
/****************************************************************************/
/* */
/* Routine Name: ips_abort_init */
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
index adc6eab..f46c382 100644
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -450,13 +450,13 @@
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
static int ips_proc24_info(char *, char **, off_t, int, int, int);
- static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
+ static void ips_select_queue_depth(struct Scsi_Host *, struct scsi_device *);
static int ips_biosparam(Disk *disk, kdev_t dev, int geom[]);
#else
static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int geom[]);
- static int ips_slave_configure(Scsi_Device *SDptr);
+ static int ips_slave_configure(struct scsi_device *SDptr);
#endif
/*
diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c
index a642f73..23728d1 100644
--- a/drivers/scsi/jazz_esp.c
+++ b/drivers/scsi/jazz_esp.c
@@ -52,7 +52,7 @@ static volatile unsigned char cmd_buffer[16];
* via PIO.
*/
-int jazz_esp_detect(Scsi_Host_Template *tpnt);
+int jazz_esp_detect(struct scsi_host_template *tpnt);
static int jazz_esp_release(struct Scsi_Host *shost)
{
if (shost->irq)
@@ -65,7 +65,7 @@ static int jazz_esp_release(struct Scsi_Host *shost)
return 0;
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "jazz_esp",
.proc_info = &esp_proc_info,
.name = "ESP 100/100a/200",
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index a74b407..665ae79 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -532,8 +532,7 @@ void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp)
* @fis: Buffer from which data will be input
* @tf: Taskfile to output
*
- * Converts a standard ATA taskfile to a Serial ATA
- * FIS structure (Register - Host to Device).
+ * Converts a serial ATA FIS structure to a standard ATA taskfile.
*
* LOCKING:
* Inherited from caller.
@@ -1047,6 +1046,30 @@ static unsigned int ata_pio_modes(const struct ata_device *adev)
return modes;
}
+static int ata_qc_wait_err(struct ata_queued_cmd *qc,
+ struct completion *wait)
+{
+ int rc = 0;
+
+ if (wait_for_completion_timeout(wait, 30 * HZ) < 1) {
+ /* timeout handling */
+ unsigned int err_mask = ac_err_mask(ata_chk_status(qc->ap));
+
+ if (!err_mask) {
+ printk(KERN_WARNING "ata%u: slow completion (cmd %x)\n",
+ qc->ap->id, qc->tf.command);
+ } else {
+ printk(KERN_WARNING "ata%u: qc timeout (cmd %x)\n",
+ qc->ap->id, qc->tf.command);
+ rc = -EIO;
+ }
+
+ ata_qc_complete(qc, err_mask);
+ }
+
+ return rc;
+}
+
/**
* ata_dev_identify - obtain IDENTIFY x DEVICE page
* @ap: port on which device we wish to probe resides
@@ -1126,7 +1149,7 @@ retry:
if (rc)
goto err_out;
else
- wait_for_completion(&wait);
+ ata_qc_wait_err(qc, &wait);
spin_lock_irqsave(&ap->host_set->lock, flags);
ap->ops->tf_read(ap, &qc->tf);
@@ -1264,7 +1287,7 @@ retry:
}
/* ATAPI-specific feature tests */
- else {
+ else if (dev->class == ATA_DEV_ATAPI) {
if (ata_id_is_ata(dev->id)) /* sanity check */
goto err_out_nosup;
@@ -1571,11 +1594,13 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
/*
* Find the mode.
- */
+ */
if (!(s = ata_timing_find_mode(speed)))
return -EINVAL;
+ memcpy(t, s, sizeof(*s));
+
/*
* If the drive is an EIDE drive, it can tell us it needs extended
* PIO/MW_DMA cycle timing.
@@ -1596,7 +1621,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
* Convert the timing to bus clock counts.
*/
- ata_timing_quantize(s, t, T, UT);
+ ata_timing_quantize(t, t, T, UT);
/*
* Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
@@ -2268,7 +2293,7 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
if (rc)
ata_port_disable(ap);
else
- wait_for_completion(&wait);
+ ata_qc_wait_err(qc, &wait);
DPRINTK("EXIT\n");
}
@@ -2316,7 +2341,7 @@ static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
if (rc)
goto err_out;
- wait_for_completion(&wait);
+ ata_qc_wait_err(qc, &wait);
swap_buf_le16(dev->id, ATA_ID_WORDS);
@@ -2372,7 +2397,7 @@ static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
if (rc)
ata_port_disable(ap);
else
- wait_for_completion(&wait);
+ ata_qc_wait_err(qc, &wait);
DPRINTK("EXIT\n");
}
@@ -2400,7 +2425,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
if (qc->flags & ATA_QCFLAG_SINGLE)
assert(qc->n_elem == 1);
- DPRINTK("unmapping %u sg elements\n", qc->n_elem);
+ VPRINTK("unmapping %u sg elements\n", qc->n_elem);
/* if we padded the buffer out to 32-bit bound, and data
* xfer direction is from-device, we must copy from the
@@ -2410,7 +2435,8 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
if (qc->flags & ATA_QCFLAG_SG) {
- dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir);
+ if (qc->n_elem)
+ dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir);
/* restore last sg */
sg[qc->orig_n_elem - 1].length += qc->pad_len;
if (pad_buf) {
@@ -2420,8 +2446,10 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
kunmap_atomic(psg->page, KM_IRQ0);
}
} else {
- dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]),
- sg_dma_len(&sg[0]), dir);
+ if (sg_dma_len(&sg[0]) > 0)
+ dma_unmap_single(ap->host_set->dev,
+ sg_dma_address(&sg[0]), sg_dma_len(&sg[0]),
+ dir);
/* restore sg */
sg->length += qc->pad_len;
if (pad_buf)
@@ -2620,6 +2648,11 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
sg->length, qc->pad_len);
}
+ if (!sg->length) {
+ sg_dma_address(sg) = 0;
+ goto skip_map;
+ }
+
dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
sg->length, dir);
if (dma_mapping_error(dma_address)) {
@@ -2629,6 +2662,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
}
sg_dma_address(sg) = dma_address;
+skip_map:
sg_dma_len(sg) = sg->length;
DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg),
@@ -2656,7 +2690,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
struct scatterlist *sg = qc->__sg;
struct scatterlist *lsg = &sg[qc->n_elem - 1];
- int n_elem, dir;
+ int n_elem, pre_n_elem, dir, trim_sg = 0;
VPRINTK("ENTER, ata%u\n", ap->id);
assert(qc->flags & ATA_QCFLAG_SG);
@@ -2690,13 +2724,24 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
sg_dma_len(psg) = ATA_DMA_PAD_SZ;
/* trim last sg */
lsg->length -= qc->pad_len;
+ if (lsg->length == 0)
+ trim_sg = 1;
DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n",
qc->n_elem - 1, lsg->length, qc->pad_len);
}
+ pre_n_elem = qc->n_elem;
+ if (trim_sg && pre_n_elem)
+ pre_n_elem--;
+
+ if (!pre_n_elem) {
+ n_elem = 0;
+ goto skip_map;
+ }
+
dir = qc->dma_dir;
- n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir);
+ n_elem = dma_map_sg(ap->host_set->dev, sg, pre_n_elem, dir);
if (n_elem < 1) {
/* restore last sg */
lsg->length += qc->pad_len;
@@ -2705,6 +2750,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
DPRINTK("%d sg elements mapped\n", n_elem);
+skip_map:
qc->n_elem = n_elem;
return 0;
@@ -3264,32 +3310,11 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_host_set *host_set = ap->host_set;
- struct ata_device *dev = qc->dev;
u8 host_stat = 0, drv_stat;
unsigned long flags;
DPRINTK("ENTER\n");
- /* FIXME: doesn't this conflict with timeout handling? */
- if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) {
- struct scsi_cmnd *cmd = qc->scsicmd;
-
- if (!(cmd->eh_eflags & SCSI_EH_CANCEL_CMD)) {
-
- /* finish completing original command */
- spin_lock_irqsave(&host_set->lock, flags);
- __ata_qc_complete(qc);
- spin_unlock_irqrestore(&host_set->lock, flags);
-
- atapi_request_sense(ap, dev, cmd);
-
- cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
- scsi_finish_command(cmd);
-
- goto out;
- }
- }
-
spin_lock_irqsave(&host_set->lock, flags);
/* hack alert! We cannot use the supplied completion
@@ -3328,7 +3353,6 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
spin_unlock_irqrestore(&host_set->lock, flags);
-out:
DPRINTK("EXIT\n");
}
@@ -3412,16 +3436,11 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
qc = ata_qc_new(ap);
if (qc) {
- qc->__sg = NULL;
- qc->flags = 0;
qc->scsicmd = NULL;
qc->ap = ap;
qc->dev = dev;
- qc->cursect = qc->cursg = qc->cursg_ofs = 0;
- qc->nsect = 0;
- qc->nbytes = qc->curbytes = 0;
- ata_tf_init(ap, &qc->tf, dev->devno);
+ ata_qc_reinit(qc);
}
return qc;
@@ -4563,6 +4582,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
+ probe_ent->private_data = port[0]->private_data;
if (ports & ATA_PORT_PRIMARY) {
probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
@@ -4599,6 +4619,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, stru
probe_ent->legacy_mode = 1;
probe_ent->n_ports = 1;
probe_ent->hard_port_no = port_num;
+ probe_ent->private_data = port->private_data;
switch(port_num)
{
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index bb30fcd..3b4ca55a 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -38,6 +38,7 @@
#include <linux/spinlock.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_eh.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_request.h>
#include <linux/libata.h>
@@ -147,7 +148,8 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
u8 scsi_cmd[MAX_COMMAND_SIZE];
u8 args[4], *argbuf = NULL;
int argsize = 0;
- struct scsi_request *sreq;
+ struct scsi_sense_hdr sshdr;
+ enum dma_data_direction data_dir;
if (NULL == (void *)arg)
return -EINVAL;
@@ -155,10 +157,6 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
if (copy_from_user(args, arg, sizeof(args)))
return -EFAULT;
- sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
- if (!sreq)
- return -EINTR;
-
memset(scsi_cmd, 0, sizeof(scsi_cmd));
if (args[3]) {
@@ -172,11 +170,11 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
scsi_cmd[1] = (4 << 1); /* PIO Data-in */
scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev,
block count in sector count field */
- sreq->sr_data_direction = DMA_FROM_DEVICE;
+ data_dir = DMA_FROM_DEVICE;
} else {
scsi_cmd[1] = (3 << 1); /* Non-data */
/* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
- sreq->sr_data_direction = DMA_NONE;
+ data_dir = DMA_NONE;
}
scsi_cmd[0] = ATA_16;
@@ -194,9 +192,8 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
/* Good values for timeout and retries? Values below
from scsi_ioctl_send_command() for default case... */
- scsi_wait_req(sreq, scsi_cmd, argbuf, argsize, (10*HZ), 5);
-
- if (sreq->sr_result) {
+ if (scsi_execute_req(scsidev, scsi_cmd, data_dir, argbuf, argsize,
+ &sshdr, (10*HZ), 5)) {
rc = -EIO;
goto error;
}
@@ -207,8 +204,6 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
&& copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize))
rc = -EFAULT;
error:
- scsi_release_request(sreq);
-
if (argbuf)
kfree(argbuf);
@@ -231,7 +226,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
int rc = 0;
u8 scsi_cmd[MAX_COMMAND_SIZE];
u8 args[7];
- struct scsi_request *sreq;
+ struct scsi_sense_hdr sshdr;
if (NULL == (void *)arg)
return -EINVAL;
@@ -250,26 +245,13 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
scsi_cmd[12] = args[5];
scsi_cmd[14] = args[0];
- sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
- if (!sreq) {
- rc = -EINTR;
- goto error;
- }
-
- sreq->sr_data_direction = DMA_NONE;
/* Good values for timeout and retries? Values below
- from scsi_ioctl_send_command() for default case... */
- scsi_wait_req(sreq, scsi_cmd, NULL, 0, (10*HZ), 5);
-
- if (sreq->sr_result) {
+ from scsi_ioctl_send_command() for default case... */
+ if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr,
+ (10*HZ), 5))
rc = -EIO;
- goto error;
- }
/* Need code to retrieve data from check condition? */
-
-error:
- scsi_release_request(sreq);
return rc;
}
@@ -1129,6 +1111,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
* length 0 means transfer 0 block of data.
* However, for ATA R/W commands, sector count 0 means
* 256 or 65536 sectors, not 0 sectors as in SCSI.
+ *
+ * WARNING: one or two older ATA drives treat 0 as 0...
*/
goto nothing_to_do;
@@ -1971,22 +1955,44 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8
done(cmd);
}
-void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
- struct scsi_cmnd *cmd)
+static int atapi_sense_complete(struct ata_queued_cmd *qc,unsigned int err_mask)
{
- DECLARE_COMPLETION(wait);
- struct ata_queued_cmd *qc;
- unsigned long flags;
- int rc;
+ if (err_mask && ((err_mask & AC_ERR_DEV) == 0))
+ /* FIXME: not quite right; we don't want the
+ * translation of taskfile registers into
+ * a sense descriptors, since that's only
+ * correct for ATA, not ATAPI
+ */
+ ata_gen_ata_desc_sense(qc);
- DPRINTK("ATAPI request sense\n");
+ qc->scsidone(qc->scsicmd);
+ return 0;
+}
- qc = ata_qc_new_init(ap, dev);
- BUG_ON(qc == NULL);
+/* is it pointless to prefer PIO for "safety reasons"? */
+static inline int ata_pio_use_silly(struct ata_port *ap)
+{
+ return (ap->flags & ATA_FLAG_PIO_DMA);
+}
+
+static void atapi_request_sense(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct scsi_cmnd *cmd = qc->scsicmd;
+
+ DPRINTK("ATAPI request sense\n");
/* FIXME: is this needed? */
memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
+ ap->ops->tf_read(ap, &qc->tf);
+
+ /* fill these in, for the case where they are -not- overwritten */
+ cmd->sense_buffer[0] = 0x70;
+ cmd->sense_buffer[2] = qc->tf.feature >> 4;
+
+ ata_qc_reinit(qc);
+
ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
qc->dma_dir = DMA_FROM_DEVICE;
@@ -1997,22 +2003,20 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
qc->tf.command = ATA_CMD_PACKET;
- qc->tf.protocol = ATA_PROT_ATAPI;
- qc->tf.lbam = (8 * 1024) & 0xff;
- qc->tf.lbah = (8 * 1024) >> 8;
+ if (ata_pio_use_silly(ap)) {
+ qc->tf.protocol = ATA_PROT_ATAPI_DMA;
+ qc->tf.feature |= ATAPI_PKT_DMA;
+ } else {
+ qc->tf.protocol = ATA_PROT_ATAPI;
+ qc->tf.lbam = (8 * 1024) & 0xff;
+ qc->tf.lbah = (8 * 1024) >> 8;
+ }
qc->nbytes = SCSI_SENSE_BUFFERSIZE;
- qc->waiting = &wait;
- qc->complete_fn = ata_qc_complete_noop;
-
- spin_lock_irqsave(&ap->host_set->lock, flags);
- rc = ata_qc_issue(qc);
- spin_unlock_irqrestore(&ap->host_set->lock, flags);
+ qc->complete_fn = atapi_sense_complete;
- if (rc)
- ata_port_disable(ap);
- else
- wait_for_completion(&wait);
+ if (ata_qc_issue(qc))
+ ata_qc_complete(qc, AC_ERR_OTHER);
DPRINTK("EXIT\n");
}
@@ -2024,19 +2028,8 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
VPRINTK("ENTER, err_mask 0x%X\n", err_mask);
if (unlikely(err_mask & AC_ERR_DEV)) {
- DPRINTK("request check condition\n");
-
- /* FIXME: command completion with check condition
- * but no sense causes the error handler to run,
- * which then issues REQUEST SENSE, fills in the sense
- * buffer, and completes the command (for the second
- * time). We need to issue REQUEST SENSE some other
- * way, to avoid completing the command twice.
- */
cmd->result = SAM_STAT_CHECK_CONDITION;
-
- qc->scsidone(cmd);
-
+ atapi_request_sense(qc);
return 1;
}
@@ -2292,6 +2285,12 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
tf->device = scsicmd[8];
tf->command = scsicmd[9];
}
+ /*
+ * If slave is possible, enforce correct master/slave bit
+ */
+ if (qc->ap->flags & ATA_FLAG_SLAVE_POSS)
+ tf->device = qc->dev->devno ?
+ tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
/*
* Filter SET_FEATURES - XFER MODE command -- otherwise,
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index fad051c..8ebaa69 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -29,7 +29,7 @@
#define __LIBATA_H__
#define DRV_NAME "libata"
-#define DRV_VERSION "1.12" /* must be exactly four chars */
+#define DRV_VERSION "1.20" /* must be exactly four chars */
struct ata_scsi_args {
u16 *id;
@@ -54,8 +54,6 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
/* libata-scsi.c */
-extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
- struct scsi_cmnd *cmd);
extern void ata_scsi_scan_host(struct ata_port *ap);
extern int ata_scsi_error(struct Scsi_Host *host);
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index c907238..0749811 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1704,7 +1704,6 @@ MODULE_DEVICE_TABLE(pci, lpfc_id_table);
static struct pci_driver lpfc_driver = {
.name = LPFC_DRIVER_NAME,
- .owner = THIS_MODULE,
.id_table = lpfc_id_table,
.probe = lpfc_pci_probe_one,
.remove = __devexit_p(lpfc_pci_remove_one),
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
index c94c8db..e31fadd6 100644
--- a/drivers/scsi/mac_esp.c
+++ b/drivers/scsi/mac_esp.c
@@ -300,7 +300,7 @@ unsigned long get_base(int chip_num)
* Model dependent ESP setup
*/
-int mac_esp_detect(Scsi_Host_Template * tpnt)
+int mac_esp_detect(struct scsi_host_template * tpnt)
{
int quick = 0;
int chipnum, chipspresent = 0;
@@ -730,7 +730,7 @@ static void dma_setup_quick(struct NCR_ESP * esp, __u32 addr, int count, int wri
#endif
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "mac_esp",
.name = "Mac 53C9x SCSI",
.detect = mac_esp_detect,
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
index 92d2c83..777f9bc 100644
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -222,7 +222,7 @@ static struct Scsi_Host *default_instance;
#endif
/*
- * Function : int macscsi_detect(Scsi_Host_Template * tpnt)
+ * Function : int macscsi_detect(struct scsi_host_template * tpnt)
*
* Purpose : initializes mac NCR5380 driver based on the
* command line / compile time port and irq definitions.
@@ -233,7 +233,7 @@ static struct Scsi_Host *default_instance;
*
*/
-int macscsi_detect(Scsi_Host_Template * tpnt)
+int macscsi_detect(struct scsi_host_template * tpnt)
{
static int called = 0;
int flags = 0;
@@ -581,7 +581,7 @@ static int macscsi_pwrite (struct Scsi_Host *instance,
#include "NCR5380.c"
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "Mac5380",
.proc_info = macscsi_proc_info,
.name = "Macintosh NCR5380 SCSI",
diff --git a/drivers/scsi/mca_53c9x.c b/drivers/scsi/mca_53c9x.c
index 194c754..998a8bb 100644
--- a/drivers/scsi/mca_53c9x.c
+++ b/drivers/scsi/mca_53c9x.c
@@ -103,7 +103,7 @@ static volatile unsigned char cmd_buffer[16];
static struct ESP_regs eregs;
/***************************************************************** Detection */
-static int mca_esp_detect(Scsi_Host_Template *tpnt)
+static int mca_esp_detect(struct scsi_host_template *tpnt)
{
struct NCR_ESP *esp;
static int io_port_by_pos[] = MCA_53C9X_IO_PORTS;
@@ -444,7 +444,7 @@ static void dma_led_off(struct NCR_ESP *esp)
outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR);
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "mca_53c9x",
.name = "NCR 53c9x SCSI",
.detect = mca_esp_detect,
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 61a6fd8..dfea346 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -362,6 +362,7 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
adapter_t *adapter;
scb_t *scb;
int busy=0;
+ unsigned long flags;
adapter = (adapter_t *)scmd->device->host->hostdata;
@@ -377,6 +378,7 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
* return 0 in that case.
*/
+ spin_lock_irqsave(&adapter->lock, flags);
scb = mega_build_cmd(adapter, scmd, &busy);
if(scb) {
@@ -393,6 +395,7 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
}
return 0;
}
+ spin_unlock_irqrestore(&adapter->lock, flags);
return busy;
}
@@ -1683,7 +1686,7 @@ mega_rundoneq (adapter_t *adapter)
list_for_each(pos, &adapter->completed_list) {
- Scsi_Pointer* spos = (Scsi_Pointer *)pos;
+ struct scsi_pointer* spos = (struct scsi_pointer *)pos;
cmd = list_entry(spos, Scsi_Cmnd, SCp);
cmd->scsi_done(cmd);
@@ -1981,7 +1984,7 @@ megaraid_reset(struct scsi_cmnd *cmd)
mc.cmd = MEGA_CLUSTER_CMD;
mc.opcode = MEGA_RESET_RESERVATIONS;
- if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) {
+ if( mega_internal_command(adapter, &mc, NULL) != 0 ) {
printk(KERN_WARNING
"megaraid: reservation reset failed.\n");
}
@@ -3011,7 +3014,7 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end )
mc.cmd = FC_NEW_CONFIG;
mc.opcode = OP_DCMD_READ_CONFIG;
- if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) {
+ if( mega_internal_command(adapter, &mc, NULL) ) {
len = sprintf(page, "40LD read config failed.\n");
@@ -3029,11 +3032,11 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end )
else {
mc.cmd = NEW_READ_CONFIG_8LD;
- if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) {
+ if( mega_internal_command(adapter, &mc, NULL) ) {
mc.cmd = READ_CONFIG_8LD;
- if( mega_internal_command(adapter, LOCK_INT, &mc,
+ if( mega_internal_command(adapter, &mc,
NULL) ){
len = sprintf(page,
@@ -3632,7 +3635,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
/*
* Issue the command
*/
- mega_internal_command(adapter, LOCK_INT, &mc, pthru);
+ mega_internal_command(adapter, &mc, pthru);
rval = mega_n_to_m((void __user *)arg, &mc);
@@ -3715,7 +3718,7 @@ freemem_and_return:
/*
* Issue the command
*/
- mega_internal_command(adapter, LOCK_INT, &mc, NULL);
+ mega_internal_command(adapter, &mc, NULL);
rval = mega_n_to_m((void __user *)arg, &mc);
@@ -4234,7 +4237,7 @@ mega_do_del_logdrv(adapter_t *adapter, int logdrv)
mc.opcode = OP_DEL_LOGDRV;
mc.subopcode = logdrv;
- rval = mega_internal_command(adapter, LOCK_INT, &mc, NULL);
+ rval = mega_internal_command(adapter, &mc, NULL);
/* log this event */
if(rval) {
@@ -4367,7 +4370,7 @@ mega_adapinq(adapter_t *adapter, dma_addr_t dma_handle)
mc.xferaddr = (u32)dma_handle;
- if ( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) {
+ if ( mega_internal_command(adapter, &mc, NULL) != 0 ) {
return -1;
}
@@ -4435,7 +4438,7 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt,
mc.cmd = MEGA_MBOXCMD_PASSTHRU;
mc.xferaddr = (u32)pthru_dma_handle;
- rval = mega_internal_command(adapter, LOCK_INT, &mc, pthru);
+ rval = mega_internal_command(adapter, &mc, pthru);
pci_free_consistent(pdev, sizeof(mega_passthru), pthru,
pthru_dma_handle);
@@ -4449,7 +4452,6 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt,
/**
* mega_internal_command()
* @adapter - pointer to our soft state
- * @ls - the scope of the exclusion lock.
* @mc - the mailbox command
* @pthru - Passthru structure for DCDB commands
*
@@ -4463,8 +4465,7 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt,
* Note: parameter 'pthru' is null for non-passthru commands.
*/
static int
-mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc,
- mega_passthru *pthru )
+mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
{
Scsi_Cmnd *scmd;
struct scsi_device *sdev;
@@ -4508,15 +4509,8 @@ mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc,
scb->idx = CMDID_INT_CMDS;
- /*
- * Get the lock only if the caller has not acquired it already
- */
- if( ls == LOCK_INT ) spin_lock_irqsave(&adapter->lock, flags);
-
megaraid_queue(scmd, mega_internal_done);
- if( ls == LOCK_INT ) spin_unlock_irqrestore(&adapter->lock, flags);
-
wait_for_completion(&adapter->int_waitq);
rval = scmd->result;
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
index 4facf55..6f90780 100644
--- a/drivers/scsi/megaraid.h
+++ b/drivers/scsi/megaraid.h
@@ -926,13 +926,6 @@ struct mega_hbas {
#define MEGA_SGLIST 0x0002
/*
- * lockscope definitions, callers can specify the lock scope with this data
- * type. LOCK_INT would mean the caller has not acquired the lock before
- * making the call and LOCK_EXT would mean otherwise.
- */
-typedef enum { LOCK_INT, LOCK_EXT } lockscope_t;
-
-/*
* Parameters for the io-mapped controllers
*/
@@ -1062,8 +1055,7 @@ static int mega_support_random_del(adapter_t *);
static int mega_del_logdrv(adapter_t *, int);
static int mega_do_del_logdrv(adapter_t *, int);
static void mega_get_max_sgl(adapter_t *);
-static int mega_internal_command(adapter_t *, lockscope_t, megacmd_t *,
- mega_passthru *);
+static int mega_internal_command(adapter_t *, megacmd_t *, mega_passthru *);
static void mega_internal_done(Scsi_Cmnd *);
static int mega_support_cluster(adapter_t *);
#endif
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h
index 8e54713..4675343 100644
--- a/drivers/scsi/megaraid/mega_common.h
+++ b/drivers/scsi/megaraid/mega_common.h
@@ -96,7 +96,6 @@ typedef struct {
* @param dpc_h : tasklet handle
* @param pdev : pci configuration pointer for kernel
* @param host : pointer to host structure of mid-layer
- * @param host_lock : pointer to appropriate lock
* @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
@@ -151,7 +150,6 @@ typedef struct {
struct tasklet_struct dpc_h;
struct pci_dev *pdev;
struct Scsi_Host *host;
- spinlock_t *host_lock;
spinlock_t lock;
uint8_t quiescent;
int outstanding_cmds;
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 1a3d195..4b5d420 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -533,8 +533,6 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
// Initialize the synchronization lock for kernel and LLD
spin_lock_init(&adapter->lock);
- adapter->host_lock = &adapter->lock;
-
// Initialize the command queues: the list of free SCBs and the list
// of pending SCBs.
@@ -715,9 +713,6 @@ megaraid_io_attach(adapter_t *adapter)
SCSIHOST2ADAP(host) = (caddr_t)adapter;
adapter->host = host;
- // export the parameters required by the mid-layer
- scsi_assign_lock(host, adapter->host_lock);
-
host->irq = adapter->irq;
host->unique_id = adapter->unique_id;
host->can_queue = adapter->max_cmds;
@@ -1560,10 +1555,6 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (* done)(struct scsi_cmnd *))
scp->scsi_done = done;
scp->result = 0;
- assert_spin_locked(adapter->host_lock);
-
- spin_unlock(adapter->host_lock);
-
/*
* Allocate and build a SCB request
* if_busy flag will be set if megaraid_mbox_build_cmd() command could
@@ -1573,23 +1564,16 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (* done)(struct scsi_cmnd *))
* return 0 in that case, and we would do the callback right away.
*/
if_busy = 0;
- scb = megaraid_mbox_build_cmd(adapter, scp, &if_busy);
-
- if (scb) {
- megaraid_mbox_runpendq(adapter, scb);
- }
-
- spin_lock(adapter->host_lock);
-
+ scb = megaraid_mbox_build_cmd(adapter, scp, &if_busy);
if (!scb) { // command already completed
done(scp);
return 0;
}
+ megaraid_mbox_runpendq(adapter, scb);
return if_busy;
}
-
/**
* megaraid_mbox_build_cmd - transform the mid-layer scsi command to megaraid
* firmware lingua
@@ -2546,9 +2530,7 @@ megaraid_mbox_dpc(unsigned long devp)
megaraid_dealloc_scb(adapter, scb);
// send the scsi packet back to kernel
- spin_lock(adapter->host_lock);
scp->scsi_done(scp);
- spin_unlock(adapter->host_lock);
}
return;
@@ -2563,7 +2545,7 @@ megaraid_mbox_dpc(unsigned long devp)
* aborted. All the commands issued to the F/W must complete.
**/
static int
-__megaraid_abort_handler(struct scsi_cmnd *scp)
+megaraid_abort_handler(struct scsi_cmnd *scp)
{
adapter_t *adapter;
mraid_device_t *raid_dev;
@@ -2577,8 +2559,6 @@ __megaraid_abort_handler(struct scsi_cmnd *scp)
adapter = SCP2ADAPTER(scp);
raid_dev = ADAP2RAIDDEV(adapter);
- assert_spin_locked(adapter->host_lock);
-
con_log(CL_ANN, (KERN_WARNING
"megaraid: aborting-%ld cmd=%x <c=%d t=%d l=%d>\n",
scp->serial_number, scp->cmnd[0], SCP2CHANNEL(scp),
@@ -2658,6 +2638,7 @@ __megaraid_abort_handler(struct scsi_cmnd *scp)
// traverse through the list of all SCB, since driver does not
// maintain these SCBs on any list
found = 0;
+ spin_lock_irq(&adapter->lock);
for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) {
scb = adapter->kscb_list + i;
@@ -2680,6 +2661,7 @@ __megaraid_abort_handler(struct scsi_cmnd *scp)
}
}
}
+ spin_unlock_irq(&adapter->lock);
if (!found) {
con_log(CL_ANN, (KERN_WARNING
@@ -2696,22 +2678,6 @@ __megaraid_abort_handler(struct scsi_cmnd *scp)
return FAILED;
}
-static int
-megaraid_abort_handler(struct scsi_cmnd *scp)
-{
- adapter_t *adapter;
- int rc;
-
- adapter = SCP2ADAPTER(scp);
-
- spin_lock_irq(adapter->host_lock);
- rc = __megaraid_abort_handler(scp);
- spin_unlock_irq(adapter->host_lock);
-
- return rc;
-}
-
-
/**
* megaraid_reset_handler - device reset hadler for mailbox based driver
* @scp : reference command
@@ -2723,7 +2689,7 @@ megaraid_abort_handler(struct scsi_cmnd *scp)
* host
**/
static int
-__megaraid_reset_handler(struct scsi_cmnd *scp)
+megaraid_reset_handler(struct scsi_cmnd *scp)
{
adapter_t *adapter;
scb_t *scb;
@@ -2739,10 +2705,6 @@ __megaraid_reset_handler(struct scsi_cmnd *scp)
adapter = SCP2ADAPTER(scp);
raid_dev = ADAP2RAIDDEV(adapter);
- assert_spin_locked(adapter->host_lock);
-
- con_log(CL_ANN, (KERN_WARNING "megaraid: reseting the host...\n"));
-
// return failure if adapter is not responding
if (raid_dev->hw_error) {
con_log(CL_ANN, (KERN_NOTICE
@@ -2779,8 +2741,6 @@ __megaraid_reset_handler(struct scsi_cmnd *scp)
adapter->outstanding_cmds, MBOX_RESET_WAIT));
}
- spin_unlock(adapter->host_lock);
-
recovery_window = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT;
recovering = adapter->outstanding_cmds;
@@ -2806,7 +2766,7 @@ __megaraid_reset_handler(struct scsi_cmnd *scp)
msleep(1000);
}
- spin_lock(adapter->host_lock);
+ spin_lock(&adapter->lock);
// If still outstanding commands, bail out
if (adapter->outstanding_cmds) {
@@ -2815,7 +2775,8 @@ __megaraid_reset_handler(struct scsi_cmnd *scp)
raid_dev->hw_error = 1;
- return FAILED;
+ rval = FAILED;
+ goto out;
}
else {
con_log(CL_ANN, (KERN_NOTICE
@@ -2824,7 +2785,10 @@ __megaraid_reset_handler(struct scsi_cmnd *scp)
// If the controller supports clustering, reset reservations
- if (!adapter->ha) return SUCCESS;
+ if (!adapter->ha) {
+ rval = SUCCESS;
+ goto out;
+ }
// clear reservations if any
raw_mbox[0] = CLUSTER_CMD;
@@ -2841,22 +2805,11 @@ __megaraid_reset_handler(struct scsi_cmnd *scp)
"megaraid: reservation reset failed\n"));
}
+ out:
+ spin_unlock_irq(&adapter->lock);
return rval;
}
-static int
-megaraid_reset_handler(struct scsi_cmnd *cmd)
-{
- int rc;
-
- spin_lock_irq(cmd->device->host->host_lock);
- rc = __megaraid_reset_handler(cmd);
- spin_unlock_irq(cmd->device->host->host_lock);
-
- return rc;
-}
-
-
/*
* START: internal commands library
*
@@ -3776,9 +3729,9 @@ wait_till_fw_empty(adapter_t *adapter)
/*
* Set the quiescent flag to stop issuing cmds to FW.
*/
- spin_lock_irqsave(adapter->host_lock, flags);
+ spin_lock_irqsave(&adapter->lock, flags);
adapter->quiescent++;
- spin_unlock_irqrestore(adapter->host_lock, flags);
+ spin_unlock_irqrestore(&adapter->lock, flags);
/*
* Wait till there are no more cmds outstanding at FW. Try for at most
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 801a63b..3c32e69 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -766,17 +766,12 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd)
return FAILED;
}
- spin_unlock(scmd->device->host->host_lock);
-
ret_val = megasas_wait_for_outstanding(instance);
-
if (ret_val == SUCCESS)
printk(KERN_NOTICE "megasas: reset successful \n");
else
printk(KERN_ERR "megasas: failed to do reset\n");
- spin_lock(scmd->device->host->host_lock);
-
return ret_val;
}
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index 33380ce..cb367c2 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -63,7 +63,7 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
m147_pcc->dma_cntrl = 0;
}
-int mvme147_detect(Scsi_Host_Template *tpnt)
+int mvme147_detect(struct scsi_host_template *tpnt)
{
static unsigned char called = 0;
wd33c93_regs regs;
@@ -130,7 +130,7 @@ static int mvme147_bus_reset(Scsi_Cmnd *cmd)
#include "mvme147.h"
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "MVME147",
.name = "MVME147 built-in SCSI",
.detect = mvme147_detect,
diff --git a/drivers/scsi/mvme147.h b/drivers/scsi/mvme147.h
index d8903f0..2f56d69 100644
--- a/drivers/scsi/mvme147.h
+++ b/drivers/scsi/mvme147.h
@@ -10,7 +10,7 @@
#include <linux/types.h>
-int mvme147_detect(Scsi_Host_Template *);
+int mvme147_detect(struct scsi_host_template *);
int mvme147_release(struct Scsi_Host *);
const char *wd33c93_info(void);
int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
diff --git a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c
index 29ec699..890e9e2 100644
--- a/drivers/scsi/mvme16x.c
+++ b/drivers/scsi/mvme16x.c
@@ -21,7 +21,7 @@
#include<linux/stat.h>
-int mvme16x_scsi_detect(Scsi_Host_Template *tpnt)
+int mvme16x_scsi_detect(struct scsi_host_template *tpnt)
{
static unsigned char called = 0;
int clock;
@@ -61,7 +61,7 @@ static int mvme16x_scsi_release(struct Scsi_Host *shost)
return 0;
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = "MVME16x NCR53c710 SCSI",
.detect = mvme16x_scsi_detect,
.release = mvme16x_scsi_release,
diff --git a/drivers/scsi/mvme16x.h b/drivers/scsi/mvme16x.h
index 25173c8..c7a1253 100644
--- a/drivers/scsi/mvme16x.h
+++ b/drivers/scsi/mvme16x.h
@@ -3,7 +3,7 @@
#include <linux/types.h>
-int mvme16x_scsi_detect(Scsi_Host_Template *);
+int mvme16x_scsi_detect(struct scsi_host_template *);
const char *NCR53c7x0_info(void);
int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int NCR53c7xx_abort(Scsi_Cmnd *);
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index e4ff4f0..a279ebb 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -198,7 +198,7 @@ static void __devexit nsp32_remove(struct pci_dev *);
static int __init init_nsp32 (void);
static void __exit exit_nsp32 (void);
-/* struct Scsi_Host_Template */
+/* struct struct scsi_host_template */
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
static int nsp32_proc_info (struct Scsi_Host *, char *, char **, off_t, int, int);
#else
@@ -208,7 +208,7 @@ static int nsp32_proc_info (char *, char **, off_t, int, int, int);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
static int nsp32_detect (struct pci_dev *pdev);
#else
-static int nsp32_detect (Scsi_Host_Template *);
+static int nsp32_detect (struct scsi_host_template *);
#endif
static int nsp32_queuecommand(struct scsi_cmnd *,
void (*done)(struct scsi_cmnd *));
@@ -2683,7 +2683,7 @@ static int nsp32_detect(struct pci_dev *pdev)
#define DETECT_OK 1
#define DETECT_NG 0
#define PCIDEV (data->Pci)
-static int nsp32_detect(Scsi_Host_Template *sht)
+static int nsp32_detect(struct scsi_host_template *sht)
#endif
{
struct Scsi_Host *host; /* registered host structure */
diff --git a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c
index 573d7ef..5d9c9ad 100644
--- a/drivers/scsi/oktagon_esp.c
+++ b/drivers/scsi/oktagon_esp.c
@@ -114,7 +114,7 @@ static volatile unsigned char cmd_buffer[16];
*/
/***************************************************************** Detection */
-int oktagon_esp_detect(Scsi_Host_Template *tpnt)
+int oktagon_esp_detect(struct scsi_host_template *tpnt)
{
struct NCR_ESP *esp;
struct zorro_dev *z = NULL;
@@ -585,7 +585,7 @@ int oktagon_esp_release(struct Scsi_Host *instance)
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "esp-oktagon",
.proc_info = &esp_proc_info,
.name = "BSC Oktagon SCSI",
diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
index 72bc947..f09e94a 100644
--- a/drivers/scsi/pas16.c
+++ b/drivers/scsi/pas16.c
@@ -369,7 +369,7 @@ void __init pas16_setup(char *str, int *ints)
}
/*
- * Function : int pas16_detect(Scsi_Host_Template * tpnt)
+ * Function : int pas16_detect(struct scsi_host_template * tpnt)
*
* Purpose : detects and initializes PAS16 controllers
* that were autoprobed, overridden on the LILO command line,
@@ -381,7 +381,7 @@ void __init pas16_setup(char *str, int *ints)
*
*/
-int __init pas16_detect(Scsi_Host_Template * tpnt)
+int __init pas16_detect(struct scsi_host_template * tpnt)
{
static int current_override = 0;
static unsigned short current_base = 0;
@@ -615,7 +615,7 @@ static int pas16_release(struct Scsi_Host *shost)
return 0;
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = "Pro Audio Spectrum-16 SCSI",
.detect = pas16_detect,
.release = pas16_release,
diff --git a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h
index 65ce1cc..8dc5b1a 100644
--- a/drivers/scsi/pas16.h
+++ b/drivers/scsi/pas16.h
@@ -117,7 +117,7 @@
static int pas16_abort(Scsi_Cmnd *);
static int pas16_biosparam(struct scsi_device *, struct block_device *,
sector_t, int*);
-static int pas16_detect(Scsi_Host_Template *);
+static int pas16_detect(struct scsi_host_template *);
static int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int pas16_bus_reset(Scsi_Cmnd *);
diff --git a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h
index 6c962d7..0ebd8ce 100644
--- a/drivers/scsi/pci2000.h
+++ b/drivers/scsi/pci2000.h
@@ -184,7 +184,7 @@ typedef struct _INQUIRYDATA
#endif
// function prototypes
-int Pci2000_Detect (Scsi_Host_Template *tpnt);
+int Pci2000_Detect (struct scsi_host_template *tpnt);
int Pci2000_Command (Scsi_Cmnd *SCpnt);
int Pci2000_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
int Pci2000_Abort (Scsi_Cmnd *SCpnt);
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 3d2f710..050ea13 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -81,7 +81,7 @@ module_param(free_ports, bool, 0);
MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
/* /usr/src/linux/drivers/scsi/hosts.h */
-static Scsi_Host_Template nsp_driver_template = {
+static struct scsi_host_template nsp_driver_template = {
.proc_name = "nsp_cs",
.proc_info = nsp_proc_info,
.name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
@@ -1310,7 +1310,7 @@ timer_out:
/*----------------------------------------------------------------*/
/* look for ninja3 card and init if found */
/*----------------------------------------------------------------*/
-static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht)
+static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
{
struct Scsi_Host *host; /* registered host structure */
nsp_hw_data *data_b = &nsp_data_base, *data;
@@ -1358,7 +1358,7 @@ static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht)
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static int nsp_detect_old(Scsi_Host_Template *sht)
+static int nsp_detect_old(struct scsi_host_template *sht)
{
if (nsp_detect(sht) == NULL) {
return 0;
@@ -1717,7 +1717,7 @@ static void nsp_cs_config(dev_link_t *link)
struct Scsi_Host *host;
nsp_hw_data *data = &nsp_data_base;
#if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
- Scsi_Device *dev;
+ struct scsi_device *dev;
dev_node_t **tail, *node;
#endif
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index c201b52..f8b9430 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -303,9 +303,9 @@ static void nsp_cs_config (dev_link_t *link);
static int nsp_cs_event (event_t event, int priority, event_callback_args_t *args);
/* Linux SCSI subsystem specific functions */
-static struct Scsi_Host *nsp_detect (Scsi_Host_Template *sht);
+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 (Scsi_Host_Template *sht);
+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);
@@ -345,7 +345,7 @@ static int nsp_expect_signal (Scsi_Cmnd *SCpnt, unsigned char current_phase,
static int nsp_xfer (Scsi_Cmnd *SCpnt, int phase);
static int nsp_dataphase_bypass (Scsi_Cmnd *SCpnt);
static int nsp_reselected (Scsi_Cmnd *SCpnt);
-static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht);
+static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht);
/* Interrupt handler */
//static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs);
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 7a516f35..bb091a4 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -72,7 +72,7 @@ static char *version = "qlogic_cs.c 1.79-ac 2002/10/26 (David Hinds)";
#define DEBUG(n, args...)
#endif
-static Scsi_Host_Template qlogicfas_driver_template = {
+static struct scsi_host_template qlogicfas_driver_template = {
.module = THIS_MODULE,
.name = qlogic_name,
.proc_name = qlogic_name,
@@ -108,7 +108,7 @@ static dev_link_t *dev_list = NULL;
static dev_info_t dev_info = "qlogic_cs";
-static struct Scsi_Host *qlogic_detect(Scsi_Host_Template *host,
+static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host,
dev_link_t *link, int qbase, int qlirq)
{
int qltyp; /* type of chip */
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index 78b4ff1..f557f17 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -190,7 +190,7 @@ static struct ata_port_info adma_port_info[] = {
},
};
-static struct pci_device_id adma_ata_pci_tbl[] = {
+static const struct pci_device_id adma_ata_pci_tbl[] = {
{ PCI_VENDOR_ID_PDC, 0x1841, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_1841_idx },
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
index c89da7d..46624ab 100644
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -71,7 +71,7 @@ static void __init pluto_detect_scsi_done(Scsi_Cmnd *SCpnt)
up(&fc_sem);
}
-int pluto_slave_configure(Scsi_Device *device)
+int pluto_slave_configure(struct scsi_device *device)
{
int depth_to_use;
@@ -90,11 +90,11 @@ int pluto_slave_configure(Scsi_Device *device)
/* Detect all SSAs attached to the machine.
To be fast, do it on all online FC channels at the same time. */
-int __init pluto_detect(Scsi_Host_Template *tpnt)
+int __init pluto_detect(struct scsi_host_template *tpnt)
{
int i, retry, nplutos;
fc_channel *fc;
- Scsi_Device dev;
+ struct scsi_device dev;
DEFINE_TIMER(fc_timer, pluto_detect_timeout, 0, 0);
tpnt->proc_name = "pluto";
@@ -339,7 +339,7 @@ static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cm
return 0;
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = "Sparc Storage Array 100/200",
.detect = pluto_detect,
.release = pluto_release,
diff --git a/drivers/scsi/pluto.h b/drivers/scsi/pluto.h
index beb844a..5da2061 100644
--- a/drivers/scsi/pluto.h
+++ b/drivers/scsi/pluto.h
@@ -38,10 +38,10 @@ struct pluto_inquiry {
/* This is the max number of outstanding SCSI commands per pluto */
#define PLUTO_CAN_QUEUE 254
-int pluto_detect(Scsi_Host_Template *);
+int pluto_detect(struct scsi_host_template *);
int pluto_release(struct Scsi_Host *);
const char * pluto_info(struct Scsi_Host *);
-int pluto_slave_configure(Scsi_Device *);
+int pluto_slave_configure(struct scsi_device *);
#endif /* !(_PLUTO_H) */
diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c
index 4322c95..5c2cdf5 100644
--- a/drivers/scsi/psi240i.c
+++ b/drivers/scsi/psi240i.c
@@ -538,7 +538,7 @@ static void ReadChipMemory (void *pdata, USHORT base, USHORT length, USHORT port
* Returns: Number of adapters found.
*
****************************************************************/
-static int Psi240i_Detect (Scsi_Host_Template *tpnt)
+static int Psi240i_Detect (struct scsi_host_template *tpnt)
{
int board;
int count = 0;
@@ -669,7 +669,7 @@ static int Psi240i_BiosParam (struct scsi_device *sdev, struct block_device *dev
MODULE_LICENSE("GPL");
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "psi240i",
.name = "PSI-240I EIDE Disk Controller",
.detect = Psi240i_Detect,
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 637fb65..0878f95 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -465,7 +465,7 @@ scsi_adjust_queue_depth(struct scsi_device *device, int tag, int depth)
}
device->queue_depth = depth;
}
-static inline struct Scsi_Host *scsi_host_alloc(Scsi_Host_Template *t, size_t s)
+static inline struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *t, size_t s)
{
return scsi_register(t, s);
}
@@ -639,10 +639,8 @@ struct qla_boards {
static struct pci_device_id qla1280_pci_tbl[] = {
{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP12160,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-#ifdef CONFIG_SCSI_QLOGIC_1280_1040
{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-#endif
{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1080,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240,
@@ -1177,7 +1175,7 @@ qla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev,
#if LINUX_VERSION_CODE < 0x020600
static int
-qla1280_detect(Scsi_Host_Template *template)
+qla1280_detect(struct scsi_host_template *template)
{
struct pci_device_id *id = &qla1280_pci_tbl[0];
struct pci_dev *pdev = NULL;
@@ -4507,7 +4505,7 @@ static struct scsi_host_template qla1280_driver_template = {
.use_clustering = ENABLE_CLUSTERING,
};
#else
-static Scsi_Host_Template qla1280_driver_template = {
+static struct scsi_host_template qla1280_driver_template = {
.proc_name = "qla1280",
.name = "Qlogic ISP 1280/12160",
.detect = qla1280_detect,
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 89793c1..5c5d231 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -970,7 +970,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
int rval;
uint32_t cnt, timer;
uint32_t risc_address;
- uint16_t mb[4];
+ uint16_t mb[4], wd;
uint32_t stat;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
@@ -1514,10 +1514,10 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
WRT_REG_DWORD(&reg->ctrl_status,
CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
- RD_REG_DWORD(&reg->ctrl_status);
+ pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
+ udelay(100);
/* Wait for firmware to complete NVRAM accesses. */
- udelay(5);
mb[0] = (uint32_t) RD_REG_WORD(&reg->mailbox0);
for (cnt = 10000 ; cnt && mb[0]; cnt--) {
udelay(5);
@@ -1525,7 +1525,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
barrier();
}
- udelay(20);
+ /* Wait for soft-reset to complete. */
for (cnt = 0; cnt < 30000; cnt++) {
if ((RD_REG_DWORD(&reg->ctrl_status) &
CSRX_ISP_SOFT_RESET) == 0)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 72d9090..2d72012 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -147,8 +147,8 @@ check_fw_ready_again:
* LIP to complete
*/
- if (atomic_read(&ha->loop_state) ==
- LOOP_DOWN && retry--) {
+ if (atomic_read(&ha->loop_state) !=
+ LOOP_READY && retry--) {
goto check_fw_ready_again;
}
wait_time--;
@@ -567,6 +567,7 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
unsigned long flags = 0;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
uint32_t cnt, d2;
+ uint16_t wd;
spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -581,10 +582,10 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
WRT_REG_DWORD(&reg->ctrl_status,
CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
- RD_REG_DWORD(&reg->ctrl_status);
+ pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
+ udelay(100);
/* Wait for firmware to complete NVRAM accesses. */
- udelay(5);
d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
for (cnt = 10000 ; cnt && d2; cnt--) {
udelay(5);
@@ -592,7 +593,7 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
barrier();
}
- udelay(20);
+ /* Wait for soft-reset to complete. */
d2 = RD_REG_DWORD(&reg->ctrl_status);
for (cnt = 6000000 ; cnt && (d2 & CSRX_ISP_SOFT_RESET); cnt--) {
udelay(5);
@@ -1258,9 +1259,15 @@ qla2x00_configure_hba(scsi_qla_host_t *ha)
rval = qla2x00_get_adapter_id(ha,
&loop_id, &al_pa, &area, &domain, &topo);
if (rval != QLA_SUCCESS) {
- qla_printk(KERN_WARNING, ha,
- "ERROR -- Unable to get host loop ID.\n");
- set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+ if (LOOP_NOT_READY(ha) || atomic_read(&ha->loop_down_timer) ||
+ (rval == QLA_COMMAND_ERROR && loop_id == 0x7)) {
+ DEBUG2(printk("%s(%ld) Loop is in a transition state\n",
+ __func__, ha->host_no));
+ } else {
+ qla_printk(KERN_WARNING, ha,
+ "ERROR -- Unable to get host loop ID.\n");
+ set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+ }
return (rval);
}
@@ -1789,7 +1796,7 @@ qla2x00_configure_loop(scsi_qla_host_t *ha)
}
if (rval == QLA_SUCCESS && test_bit(RSCN_UPDATE, &flags)) {
- if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
+ if (LOOP_NOT_READY(ha)) {
rval = QLA_FUNCTION_FAILED;
} else {
rval = qla2x00_configure_fabric(ha);
@@ -2362,8 +2369,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
if (qla2x00_is_reserved_id(ha, loop_id))
continue;
- if (atomic_read(&ha->loop_down_timer) ||
- test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags))
+ if (atomic_read(&ha->loop_down_timer) || LOOP_NOT_READY(ha))
break;
if (swl != NULL) {
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index ad3cacb..9746cd1 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -868,10 +868,6 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp)
DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no);)
fcport = sp->fcport;
- if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
- atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
- return 1;
- }
spin_lock_irqsave(&ha->hardware_lock, flags);
for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
@@ -1008,6 +1004,8 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
mcp->tov = 30;
mcp->flags = 0;
rval = qla2x00_mailbox_command(ha, mcp);
+ if (mcp->mb[0] == MBS_COMMAND_ERROR)
+ rval = QLA_COMMAND_ERROR;
/* Return data. */
*id = mcp->mb[1];
@@ -2179,10 +2177,6 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp)
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
fcport = sp->fcport;
- if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
- atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
- return QLA_FUNCTION_FAILED;
- }
spin_lock_irqsave(&ha->hardware_lock, flags);
for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 4bec0b4..d54d2a9 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -126,6 +126,7 @@ qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data)
/* Wait for NVRAM to become ready */
WRT_REG_WORD(&reg->nvram, NVR_SELECT);
+ RD_REG_WORD(&reg->nvram); /* PCI Posting. */
do {
NVRAM_DELAY();
word = RD_REG_WORD(&reg->nvram);
@@ -178,6 +179,7 @@ qla2x00_write_nvram_word_tmo(scsi_qla_host_t *ha, uint32_t addr, uint16_t data,
/* Wait for NVRAM to become ready */
WRT_REG_WORD(&reg->nvram, NVR_SELECT);
+ RD_REG_WORD(&reg->nvram); /* PCI Posting. */
do {
NVRAM_DELAY();
word = RD_REG_WORD(&reg->nvram);
@@ -235,6 +237,7 @@ qla2x00_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd)
/* Read data from NVRAM. */
for (cnt = 0; cnt < 16; cnt++) {
WRT_REG_WORD(&reg->nvram, NVR_SELECT | NVR_CLOCK);
+ RD_REG_WORD(&reg->nvram); /* PCI Posting. */
NVRAM_DELAY();
data <<= 1;
reg_data = RD_REG_WORD(&reg->nvram);
@@ -337,6 +340,7 @@ qla2x00_clear_nvram_protection(scsi_qla_host_t *ha)
/* Wait for NVRAM to become ready. */
WRT_REG_WORD(&reg->nvram, NVR_SELECT);
+ RD_REG_WORD(&reg->nvram); /* PCI Posting. */
do {
NVRAM_DELAY();
word = RD_REG_WORD(&reg->nvram);
@@ -388,6 +392,7 @@ qla2x00_set_nvram_protection(scsi_qla_host_t *ha, int stat)
/* Wait for NVRAM to become ready. */
WRT_REG_WORD(&reg->nvram, NVR_SELECT);
+ RD_REG_WORD(&reg->nvram); /* PCI Posting. */
do {
NVRAM_DELAY();
word = RD_REG_WORD(&reg->nvram);
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 0d5472f..f7937f7 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.01.00-k"
+#define QLA2XXX_VERSION "8.01.03-k"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 1
-#define QLA_DRIVER_PATCH_VER 0
+#define QLA_DRIVER_PATCH_VER 3
#define QLA_DRIVER_BETA_VER 0
diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
index 55e698b..94baca8 100644
--- a/drivers/scsi/qlogicfas.c
+++ b/drivers/scsi/qlogicfas.c
@@ -47,7 +47,7 @@ static char qlogicfas_name[] = "qlogicfas";
* Look for qlogic card and init if found
*/
-static struct Scsi_Host *__qlogicfas_detect(Scsi_Host_Template *host,
+static struct Scsi_Host *__qlogicfas_detect(struct scsi_host_template *host,
int qbase,
int qlirq)
{
@@ -142,7 +142,7 @@ module_param_array(irq, int, NULL, 0);
MODULE_PARM_DESC(iobase, "I/O address");
MODULE_PARM_DESC(irq, "IRQ");
-static int __devinit qlogicfas_detect(Scsi_Host_Template *sht)
+static int __devinit qlogicfas_detect(struct scsi_host_template *sht)
{
struct Scsi_Host *shost;
struct qlogicfas408_priv *priv;
@@ -183,7 +183,7 @@ static int qlogicfas_release(struct Scsi_Host *shost)
/*
* The driver template is also needed for PCMCIA
*/
-static Scsi_Host_Template qlogicfas_driver_template = {
+static struct scsi_host_template qlogicfas_driver_template = {
.module = THIS_MODULE,
.name = qlogicfas_name,
.proc_name = qlogicfas_name,
diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
index a4b3b3f..94ef3f0 100644
--- a/drivers/scsi/qlogicfc.c
+++ b/drivers/scsi/qlogicfc.c
@@ -711,7 +711,7 @@ static inline void isp2x00_disable_irqs(struct Scsi_Host *host)
}
-static int isp2x00_detect(Scsi_Host_Template * tmpt)
+static int isp2x00_detect(struct scsi_host_template * tmpt)
{
int hosts = 0;
unsigned long wait_time;
@@ -2210,7 +2210,7 @@ void isp2x00_print_scsi_cmd(Scsi_Cmnd * cmd)
MODULE_LICENSE("GPL");
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.detect = isp2x00_detect,
.release = isp2x00_release,
.info = isp2x00_info,
diff --git a/drivers/scsi/qlogicisp.c b/drivers/scsi/qlogicisp.c
deleted file mode 100644
index 6c9266b..0000000
--- a/drivers/scsi/qlogicisp.c
+++ /dev/null
@@ -1,1934 +0,0 @@
-/*
- * QLogic ISP1020 Intelligent SCSI Processor Driver (PCI)
- * Written by Erik H. Moe, ehm@cris.com
- * Copyright 1995, Erik H. Moe
- * Copyright 1996, 1997 Michael A. Griffith <grif@acm.org>
- * Copyright 2000, Jayson C. Vantuyl <vantuyl@csc.smsu.edu>
- * and Bryon W. Roche <bryon@csc.smsu.edu>
- *
- * 64-bit addressing added by Kanoj Sarcar <kanoj@sgi.com>
- * and Leo Dagum <dagum@sgi.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.
- */
-
-#include <linux/blkdev.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/unistd.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/byteorder.h>
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-
-/*
- * With the qlogic interface, every queue slot can hold a SCSI
- * command with up to 4 scatter/gather entries. If we need more
- * than 4 entries, continuation entries can be used that hold
- * another 7 entries each. Unlike for other drivers, this means
- * that the maximum number of scatter/gather entries we can
- * support at any given time is a function of the number of queue
- * slots available. That is, host->can_queue and host->sg_tablesize
- * are dynamic and _not_ independent. This all works fine because
- * requests are queued serially and the scatter/gather limit is
- * determined for each queue request anew.
- */
-#define QLOGICISP_REQ_QUEUE_LEN 63 /* must be power of two - 1 */
-#define QLOGICISP_MAX_SG(ql) (4 + ((ql) > 0) ? 7*((ql) - 1) : 0)
-
-/* Configuration section *****************************************************/
-
-/* Set the following macro to 1 to reload the ISP1020's firmware. This is
- the latest firmware provided by QLogic. This may be an earlier/later
- revision than supplied by your board. */
-
-#define RELOAD_FIRMWARE 1
-
-/* Set the following macro to 1 to reload the ISP1020's defaults from nvram.
- If you are not sure of your settings, leave this alone, the driver will
- use a set of 'safe' defaults */
-
-#define USE_NVRAM_DEFAULTS 0
-
-/* Macros used for debugging */
-
-#define DEBUG_ISP1020 0
-#define DEBUG_ISP1020_INTR 0
-#define DEBUG_ISP1020_SETUP 0
-#define TRACE_ISP 0
-
-#define DEFAULT_LOOP_COUNT 1000000
-
-/* End Configuration section *************************************************/
-
-#include <linux/module.h>
-
-#if TRACE_ISP
-
-# define TRACE_BUF_LEN (32*1024)
-
-struct {
- u_long next;
- struct {
- u_long time;
- u_int index;
- u_int addr;
- u_char * name;
- } buf[TRACE_BUF_LEN];
-} trace;
-
-#define TRACE(w, i, a) \
-{ \
- unsigned long flags; \
- \
- trace.buf[trace.next].name = (w); \
- trace.buf[trace.next].time = jiffies; \
- trace.buf[trace.next].index = (i); \
- trace.buf[trace.next].addr = (long) (a); \
- trace.next = (trace.next + 1) & (TRACE_BUF_LEN - 1); \
-}
-
-#else
-# define TRACE(w, i, a)
-#endif
-
-#if DEBUG_ISP1020
-#define ENTER(x) printk("isp1020 : entering %s()\n", x);
-#define LEAVE(x) printk("isp1020 : leaving %s()\n", x);
-#define DEBUG(x) x
-#else
-#define ENTER(x)
-#define LEAVE(x)
-#define DEBUG(x)
-#endif /* DEBUG_ISP1020 */
-
-#if DEBUG_ISP1020_INTR
-#define ENTER_INTR(x) printk("isp1020 : entering %s()\n", x);
-#define LEAVE_INTR(x) printk("isp1020 : leaving %s()\n", x);
-#define DEBUG_INTR(x) x
-#else
-#define ENTER_INTR(x)
-#define LEAVE_INTR(x)
-#define DEBUG_INTR(x)
-#endif /* DEBUG ISP1020_INTR */
-
-#define ISP1020_REV_ID 1
-
-#define MAX_TARGETS 16
-#define MAX_LUNS 8
-
-/* host configuration and control registers */
-#define HOST_HCCR 0xc0 /* host command and control */
-
-/* pci bus interface registers */
-#define PCI_ID_LOW 0x00 /* vendor id */
-#define PCI_ID_HIGH 0x02 /* device id */
-#define ISP_CFG0 0x04 /* configuration register #0 */
-#define ISP_CFG0_HWMSK 0x000f /* Hardware revision mask */
-#define ISP_CFG0_1020 0x0001 /* ISP1020 */
-#define ISP_CFG0_1020A 0x0002 /* ISP1020A */
-#define ISP_CFG0_1040 0x0003 /* ISP1040 */
-#define ISP_CFG0_1040A 0x0004 /* ISP1040A */
-#define ISP_CFG0_1040B 0x0005 /* ISP1040B */
-#define ISP_CFG0_1040C 0x0006 /* ISP1040C */
-#define ISP_CFG1 0x06 /* configuration register #1 */
-#define ISP_CFG1_F128 0x0040 /* 128-byte FIFO threshold */
-#define ISP_CFG1_F64 0x0030 /* 128-byte FIFO threshold */
-#define ISP_CFG1_F32 0x0020 /* 128-byte FIFO threshold */
-#define ISP_CFG1_F16 0x0010 /* 128-byte FIFO threshold */
-#define ISP_CFG1_BENAB 0x0004 /* Global Bus burst enable */
-#define ISP_CFG1_SXP 0x0001 /* SXP register select */
-#define PCI_INTF_CTL 0x08 /* pci interface control */
-#define PCI_INTF_STS 0x0a /* pci interface status */
-#define PCI_SEMAPHORE 0x0c /* pci semaphore */
-#define PCI_NVRAM 0x0e /* pci nvram interface */
-#define CDMA_CONF 0x20 /* Command DMA Config */
-#define DDMA_CONF 0x40 /* Data DMA Config */
-#define DMA_CONF_SENAB 0x0008 /* SXP to DMA Data enable */
-#define DMA_CONF_RIRQ 0x0004 /* RISC interrupt enable */
-#define DMA_CONF_BENAB 0x0002 /* Bus burst enable */
-#define DMA_CONF_DIR 0x0001 /* DMA direction (0=fifo->host 1=host->fifo) */
-
-/* mailbox registers */
-#define MBOX0 0x70 /* mailbox 0 */
-#define MBOX1 0x72 /* mailbox 1 */
-#define MBOX2 0x74 /* mailbox 2 */
-#define MBOX3 0x76 /* mailbox 3 */
-#define MBOX4 0x78 /* mailbox 4 */
-#define MBOX5 0x7a /* mailbox 5 */
-#define MBOX6 0x7c /* mailbox 6 */
-#define MBOX7 0x7e /* mailbox 7 */
-
-/* mailbox command complete status codes */
-#define MBOX_COMMAND_COMPLETE 0x4000
-#define INVALID_COMMAND 0x4001
-#define HOST_INTERFACE_ERROR 0x4002
-#define TEST_FAILED 0x4003
-#define COMMAND_ERROR 0x4005
-#define COMMAND_PARAM_ERROR 0x4006
-
-/* async event status codes */
-#define ASYNC_SCSI_BUS_RESET 0x8001
-#define SYSTEM_ERROR 0x8002
-#define REQUEST_TRANSFER_ERROR 0x8003
-#define RESPONSE_TRANSFER_ERROR 0x8004
-#define REQUEST_QUEUE_WAKEUP 0x8005
-#define EXECUTION_TIMEOUT_RESET 0x8006
-
-#ifdef CONFIG_QL_ISP_A64
-#define IOCB_SEGS 2
-#define CONTINUATION_SEGS 5
-#define MAX_CONTINUATION_ENTRIES 254
-#else
-#define IOCB_SEGS 4
-#define CONTINUATION_SEGS 7
-#endif /* CONFIG_QL_ISP_A64 */
-
-struct Entry_header {
- u_char entry_type;
- u_char entry_cnt;
- u_char sys_def_1;
- u_char flags;
-};
-
-/* entry header type commands */
-#ifdef CONFIG_QL_ISP_A64
-#define ENTRY_COMMAND 9
-#define ENTRY_CONTINUATION 0xa
-#else
-#define ENTRY_COMMAND 1
-#define ENTRY_CONTINUATION 2
-#endif /* CONFIG_QL_ISP_A64 */
-
-#define ENTRY_STATUS 3
-#define ENTRY_MARKER 4
-#define ENTRY_EXTENDED_COMMAND 5
-
-/* entry header flag definitions */
-#define EFLAG_CONTINUATION 1
-#define EFLAG_BUSY 2
-#define EFLAG_BAD_HEADER 4
-#define EFLAG_BAD_PAYLOAD 8
-
-struct dataseg {
- u_int d_base;
-#ifdef CONFIG_QL_ISP_A64
- u_int d_base_hi;
-#endif
- u_int d_count;
-};
-
-struct Command_Entry {
- struct Entry_header hdr;
- u_int handle;
- u_char target_lun;
- u_char target_id;
- u_short cdb_length;
- u_short control_flags;
- u_short rsvd;
- u_short time_out;
- u_short segment_cnt;
- u_char cdb[12];
-#ifdef CONFIG_QL_ISP_A64
- u_int rsvd1;
- u_int rsvd2;
-#endif
- struct dataseg dataseg[IOCB_SEGS];
-};
-
-/* command entry control flag definitions */
-#define CFLAG_NODISC 0x01
-#define CFLAG_HEAD_TAG 0x02
-#define CFLAG_ORDERED_TAG 0x04
-#define CFLAG_SIMPLE_TAG 0x08
-#define CFLAG_TAR_RTN 0x10
-#define CFLAG_READ 0x20
-#define CFLAG_WRITE 0x40
-
-struct Ext_Command_Entry {
- struct Entry_header hdr;
- u_int handle;
- u_char target_lun;
- u_char target_id;
- u_short cdb_length;
- u_short control_flags;
- u_short rsvd;
- u_short time_out;
- u_short segment_cnt;
- u_char cdb[44];
-};
-
-struct Continuation_Entry {
- struct Entry_header hdr;
-#ifndef CONFIG_QL_ISP_A64
- u_int reserved;
-#endif
- struct dataseg dataseg[CONTINUATION_SEGS];
-};
-
-struct Marker_Entry {
- struct Entry_header hdr;
- u_int reserved;
- u_char target_lun;
- u_char target_id;
- u_char modifier;
- u_char rsvd;
- u_char rsvds[52];
-};
-
-/* marker entry modifier definitions */
-#define SYNC_DEVICE 0
-#define SYNC_TARGET 1
-#define SYNC_ALL 2
-
-struct Status_Entry {
- struct Entry_header hdr;
- u_int handle;
- u_short scsi_status;
- u_short completion_status;
- u_short state_flags;
- u_short status_flags;
- u_short time;
- u_short req_sense_len;
- u_int residual;
- u_char rsvd[8];
- u_char req_sense_data[32];
-};
-
-/* status entry completion status definitions */
-#define CS_COMPLETE 0x0000
-#define CS_INCOMPLETE 0x0001
-#define CS_DMA_ERROR 0x0002
-#define CS_TRANSPORT_ERROR 0x0003
-#define CS_RESET_OCCURRED 0x0004
-#define CS_ABORTED 0x0005
-#define CS_TIMEOUT 0x0006
-#define CS_DATA_OVERRUN 0x0007
-#define CS_COMMAND_OVERRUN 0x0008
-#define CS_STATUS_OVERRUN 0x0009
-#define CS_BAD_MESSAGE 0x000a
-#define CS_NO_MESSAGE_OUT 0x000b
-#define CS_EXT_ID_FAILED 0x000c
-#define CS_IDE_MSG_FAILED 0x000d
-#define CS_ABORT_MSG_FAILED 0x000e
-#define CS_REJECT_MSG_FAILED 0x000f
-#define CS_NOP_MSG_FAILED 0x0010
-#define CS_PARITY_ERROR_MSG_FAILED 0x0011
-#define CS_DEVICE_RESET_MSG_FAILED 0x0012
-#define CS_ID_MSG_FAILED 0x0013
-#define CS_UNEXP_BUS_FREE 0x0014
-#define CS_DATA_UNDERRUN 0x0015
-
-/* status entry state flag definitions */
-#define SF_GOT_BUS 0x0100
-#define SF_GOT_TARGET 0x0200
-#define SF_SENT_CDB 0x0400
-#define SF_TRANSFERRED_DATA 0x0800
-#define SF_GOT_STATUS 0x1000
-#define SF_GOT_SENSE 0x2000
-
-/* status entry status flag definitions */
-#define STF_DISCONNECT 0x0001
-#define STF_SYNCHRONOUS 0x0002
-#define STF_PARITY_ERROR 0x0004
-#define STF_BUS_RESET 0x0008
-#define STF_DEVICE_RESET 0x0010
-#define STF_ABORTED 0x0020
-#define STF_TIMEOUT 0x0040
-#define STF_NEGOTIATION 0x0080
-
-/* interface control commands */
-#define ISP_RESET 0x0001
-#define ISP_EN_INT 0x0002
-#define ISP_EN_RISC 0x0004
-
-/* host control commands */
-#define HCCR_NOP 0x0000
-#define HCCR_RESET 0x1000
-#define HCCR_PAUSE 0x2000
-#define HCCR_RELEASE 0x3000
-#define HCCR_SINGLE_STEP 0x4000
-#define HCCR_SET_HOST_INTR 0x5000
-#define HCCR_CLEAR_HOST_INTR 0x6000
-#define HCCR_CLEAR_RISC_INTR 0x7000
-#define HCCR_BP_ENABLE 0x8000
-#define HCCR_BIOS_DISABLE 0x9000
-#define HCCR_TEST_MODE 0xf000
-
-#define RISC_BUSY 0x0004
-
-/* mailbox commands */
-#define MBOX_NO_OP 0x0000
-#define MBOX_LOAD_RAM 0x0001
-#define MBOX_EXEC_FIRMWARE 0x0002
-#define MBOX_DUMP_RAM 0x0003
-#define MBOX_WRITE_RAM_WORD 0x0004
-#define MBOX_READ_RAM_WORD 0x0005
-#define MBOX_MAILBOX_REG_TEST 0x0006
-#define MBOX_VERIFY_CHECKSUM 0x0007
-#define MBOX_ABOUT_FIRMWARE 0x0008
-#define MBOX_CHECK_FIRMWARE 0x000e
-#define MBOX_INIT_REQ_QUEUE 0x0010
-#define MBOX_INIT_RES_QUEUE 0x0011
-#define MBOX_EXECUTE_IOCB 0x0012
-#define MBOX_WAKE_UP 0x0013
-#define MBOX_STOP_FIRMWARE 0x0014
-#define MBOX_ABORT 0x0015
-#define MBOX_ABORT_DEVICE 0x0016
-#define MBOX_ABORT_TARGET 0x0017
-#define MBOX_BUS_RESET 0x0018
-#define MBOX_STOP_QUEUE 0x0019
-#define MBOX_START_QUEUE 0x001a
-#define MBOX_SINGLE_STEP_QUEUE 0x001b
-#define MBOX_ABORT_QUEUE 0x001c
-#define MBOX_GET_DEV_QUEUE_STATUS 0x001d
-#define MBOX_GET_FIRMWARE_STATUS 0x001f
-#define MBOX_GET_INIT_SCSI_ID 0x0020
-#define MBOX_GET_SELECT_TIMEOUT 0x0021
-#define MBOX_GET_RETRY_COUNT 0x0022
-#define MBOX_GET_TAG_AGE_LIMIT 0x0023
-#define MBOX_GET_CLOCK_RATE 0x0024
-#define MBOX_GET_ACT_NEG_STATE 0x0025
-#define MBOX_GET_ASYNC_DATA_SETUP_TIME 0x0026
-#define MBOX_GET_PCI_PARAMS 0x0027
-#define MBOX_GET_TARGET_PARAMS 0x0028
-#define MBOX_GET_DEV_QUEUE_PARAMS 0x0029
-#define MBOX_SET_INIT_SCSI_ID 0x0030
-#define MBOX_SET_SELECT_TIMEOUT 0x0031
-#define MBOX_SET_RETRY_COUNT 0x0032
-#define MBOX_SET_TAG_AGE_LIMIT 0x0033
-#define MBOX_SET_CLOCK_RATE 0x0034
-#define MBOX_SET_ACTIVE_NEG_STATE 0x0035
-#define MBOX_SET_ASYNC_DATA_SETUP_TIME 0x0036
-#define MBOX_SET_PCI_CONTROL_PARAMS 0x0037
-#define MBOX_SET_TARGET_PARAMS 0x0038
-#define MBOX_SET_DEV_QUEUE_PARAMS 0x0039
-#define MBOX_RETURN_BIOS_BLOCK_ADDR 0x0040
-#define MBOX_WRITE_FOUR_RAM_WORDS 0x0041
-#define MBOX_EXEC_BIOS_IOCB 0x0042
-
-#ifdef CONFIG_QL_ISP_A64
-#define MBOX_CMD_INIT_REQUEST_QUEUE_64 0x0052
-#define MBOX_CMD_INIT_RESPONSE_QUEUE_64 0x0053
-#endif /* CONFIG_QL_ISP_A64 */
-
-#include "qlogicisp_asm.c"
-
-#define PACKB(a, b) (((a)<<4)|(b))
-
-static const u_char mbox_param[] = {
- PACKB(1, 1), /* MBOX_NO_OP */
- PACKB(5, 5), /* MBOX_LOAD_RAM */
- PACKB(2, 0), /* MBOX_EXEC_FIRMWARE */
- PACKB(5, 5), /* MBOX_DUMP_RAM */
- PACKB(3, 3), /* MBOX_WRITE_RAM_WORD */
- PACKB(2, 3), /* MBOX_READ_RAM_WORD */
- PACKB(6, 6), /* MBOX_MAILBOX_REG_TEST */
- PACKB(2, 3), /* MBOX_VERIFY_CHECKSUM */
- PACKB(1, 3), /* MBOX_ABOUT_FIRMWARE */
- PACKB(0, 0), /* 0x0009 */
- PACKB(0, 0), /* 0x000a */
- PACKB(0, 0), /* 0x000b */
- PACKB(0, 0), /* 0x000c */
- PACKB(0, 0), /* 0x000d */
- PACKB(1, 2), /* MBOX_CHECK_FIRMWARE */
- PACKB(0, 0), /* 0x000f */
- PACKB(5, 5), /* MBOX_INIT_REQ_QUEUE */
- PACKB(6, 6), /* MBOX_INIT_RES_QUEUE */
- PACKB(4, 4), /* MBOX_EXECUTE_IOCB */
- PACKB(2, 2), /* MBOX_WAKE_UP */
- PACKB(1, 6), /* MBOX_STOP_FIRMWARE */
- PACKB(4, 4), /* MBOX_ABORT */
- PACKB(2, 2), /* MBOX_ABORT_DEVICE */
- PACKB(3, 3), /* MBOX_ABORT_TARGET */
- PACKB(2, 2), /* MBOX_BUS_RESET */
- PACKB(2, 3), /* MBOX_STOP_QUEUE */
- PACKB(2, 3), /* MBOX_START_QUEUE */
- PACKB(2, 3), /* MBOX_SINGLE_STEP_QUEUE */
- PACKB(2, 3), /* MBOX_ABORT_QUEUE */
- PACKB(2, 4), /* MBOX_GET_DEV_QUEUE_STATUS */
- PACKB(0, 0), /* 0x001e */
- PACKB(1, 3), /* MBOX_GET_FIRMWARE_STATUS */
- PACKB(1, 2), /* MBOX_GET_INIT_SCSI_ID */
- PACKB(1, 2), /* MBOX_GET_SELECT_TIMEOUT */
- PACKB(1, 3), /* MBOX_GET_RETRY_COUNT */
- PACKB(1, 2), /* MBOX_GET_TAG_AGE_LIMIT */
- PACKB(1, 2), /* MBOX_GET_CLOCK_RATE */
- PACKB(1, 2), /* MBOX_GET_ACT_NEG_STATE */
- PACKB(1, 2), /* MBOX_GET_ASYNC_DATA_SETUP_TIME */
- PACKB(1, 3), /* MBOX_GET_PCI_PARAMS */
- PACKB(2, 4), /* MBOX_GET_TARGET_PARAMS */
- PACKB(2, 4), /* MBOX_GET_DEV_QUEUE_PARAMS */
- PACKB(0, 0), /* 0x002a */
- PACKB(0, 0), /* 0x002b */
- PACKB(0, 0), /* 0x002c */
- PACKB(0, 0), /* 0x002d */
- PACKB(0, 0), /* 0x002e */
- PACKB(0, 0), /* 0x002f */
- PACKB(2, 2), /* MBOX_SET_INIT_SCSI_ID */
- PACKB(2, 2), /* MBOX_SET_SELECT_TIMEOUT */
- PACKB(3, 3), /* MBOX_SET_RETRY_COUNT */
- PACKB(2, 2), /* MBOX_SET_TAG_AGE_LIMIT */
- PACKB(2, 2), /* MBOX_SET_CLOCK_RATE */
- PACKB(2, 2), /* MBOX_SET_ACTIVE_NEG_STATE */
- PACKB(2, 2), /* MBOX_SET_ASYNC_DATA_SETUP_TIME */
- PACKB(3, 3), /* MBOX_SET_PCI_CONTROL_PARAMS */
- PACKB(4, 4), /* MBOX_SET_TARGET_PARAMS */
- PACKB(4, 4), /* MBOX_SET_DEV_QUEUE_PARAMS */
- PACKB(0, 0), /* 0x003a */
- PACKB(0, 0), /* 0x003b */
- PACKB(0, 0), /* 0x003c */
- PACKB(0, 0), /* 0x003d */
- PACKB(0, 0), /* 0x003e */
- PACKB(0, 0), /* 0x003f */
- PACKB(1, 2), /* MBOX_RETURN_BIOS_BLOCK_ADDR */
- PACKB(6, 1), /* MBOX_WRITE_FOUR_RAM_WORDS */
- PACKB(2, 3) /* MBOX_EXEC_BIOS_IOCB */
-#ifdef CONFIG_QL_ISP_A64
- ,PACKB(0, 0), /* 0x0043 */
- PACKB(0, 0), /* 0x0044 */
- PACKB(0, 0), /* 0x0045 */
- PACKB(0, 0), /* 0x0046 */
- PACKB(0, 0), /* 0x0047 */
- PACKB(0, 0), /* 0x0048 */
- PACKB(0, 0), /* 0x0049 */
- PACKB(0, 0), /* 0x004a */
- PACKB(0, 0), /* 0x004b */
- PACKB(0, 0), /* 0x004c */
- PACKB(0, 0), /* 0x004d */
- PACKB(0, 0), /* 0x004e */
- PACKB(0, 0), /* 0x004f */
- PACKB(0, 0), /* 0x0050 */
- PACKB(0, 0), /* 0x0051 */
- PACKB(8, 8), /* MBOX_CMD_INIT_REQUEST_QUEUE_64 (0x0052) */
- PACKB(8, 8) /* MBOX_CMD_INIT_RESPONSE_QUEUE_64 (0x0053) */
-#endif /* CONFIG_QL_ISP_A64 */
-};
-
-#define MAX_MBOX_COMMAND (sizeof(mbox_param)/sizeof(u_short))
-
-struct host_param {
- u_short fifo_threshold;
- u_short host_adapter_enable;
- u_short initiator_scsi_id;
- u_short bus_reset_delay;
- u_short retry_count;
- u_short retry_delay;
- u_short async_data_setup_time;
- u_short req_ack_active_negation;
- u_short data_line_active_negation;
- u_short data_dma_burst_enable;
- u_short command_dma_burst_enable;
- u_short tag_aging;
- u_short selection_timeout;
- u_short max_queue_depth;
-};
-
-/*
- * Device Flags:
- *
- * Bit Name
- * ---------
- * 7 Disconnect Privilege
- * 6 Parity Checking
- * 5 Wide Data Transfers
- * 4 Synchronous Data Transfers
- * 3 Tagged Queuing
- * 2 Automatic Request Sense
- * 1 Stop Queue on Check Condition
- * 0 Renegotiate on Error
- */
-
-struct dev_param {
- u_short device_flags;
- u_short execution_throttle;
- u_short synchronous_period;
- u_short synchronous_offset;
- u_short device_enable;
- u_short reserved; /* pad */
-};
-
-/*
- * The result queue can be quite a bit smaller since continuation entries
- * do not show up there:
- */
-#define RES_QUEUE_LEN ((QLOGICISP_REQ_QUEUE_LEN + 1) / 8 - 1)
-#define QUEUE_ENTRY_LEN 64
-#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
-
-struct isp_queue_entry {
- char __opaque[QUEUE_ENTRY_LEN];
-};
-
-struct isp1020_hostdata {
- void __iomem *memaddr;
- u_char revision;
- struct host_param host_param;
- struct dev_param dev_param[MAX_TARGETS];
- struct pci_dev *pci_dev;
-
- struct isp_queue_entry *res_cpu; /* CPU-side address of response queue. */
- struct isp_queue_entry *req_cpu; /* CPU-size address of request queue. */
-
- /* result and request queues (shared with isp1020): */
- u_int req_in_ptr; /* index of next request slot */
- u_int res_out_ptr; /* index of next result slot */
-
- /* this is here so the queues are nicely aligned */
- long send_marker; /* do we need to send a marker? */
-
- /* The cmd->handle has a fixed size, and is only 32-bits. We
- * need to take care to handle 64-bit systems correctly thus what
- * we actually place in cmd->handle is an index to the following
- * table. Kudos to Matt Jacob for the technique. -DaveM
- */
- Scsi_Cmnd *cmd_slots[QLOGICISP_REQ_QUEUE_LEN + 1];
-
- dma_addr_t res_dma; /* PCI side view of response queue */
- dma_addr_t req_dma; /* PCI side view of request queue */
-};
-
-/* queue length's _must_ be power of two: */
-#define QUEUE_DEPTH(in, out, ql) ((in - out) & (ql))
-#define REQ_QUEUE_DEPTH(in, out) QUEUE_DEPTH(in, out, \
- QLOGICISP_REQ_QUEUE_LEN)
-#define RES_QUEUE_DEPTH(in, out) QUEUE_DEPTH(in, out, RES_QUEUE_LEN)
-
-static void isp1020_enable_irqs(struct Scsi_Host *);
-static void isp1020_disable_irqs(struct Scsi_Host *);
-static int isp1020_init(struct Scsi_Host *);
-static int isp1020_reset_hardware(struct Scsi_Host *);
-static int isp1020_set_defaults(struct Scsi_Host *);
-static int isp1020_load_parameters(struct Scsi_Host *);
-static int isp1020_mbox_command(struct Scsi_Host *, u_short []);
-static int isp1020_return_status(struct Status_Entry *);
-static void isp1020_intr_handler(int, void *, struct pt_regs *);
-static irqreturn_t do_isp1020_intr_handler(int, void *, struct pt_regs *);
-
-#if USE_NVRAM_DEFAULTS
-static int isp1020_get_defaults(struct Scsi_Host *);
-static int isp1020_verify_nvram(struct Scsi_Host *);
-static u_short isp1020_read_nvram_word(struct Scsi_Host *, u_short);
-#endif
-
-#if DEBUG_ISP1020
-static void isp1020_print_scsi_cmd(Scsi_Cmnd *);
-#endif
-#if DEBUG_ISP1020_INTR
-static void isp1020_print_status_entry(struct Status_Entry *);
-#endif
-
-/* memaddr should be used to determine if memmapped port i/o is being used
- * non-null memaddr == mmap'd
- * JV 7-Jan-2000
- */
-static inline u_short isp_inw(struct Scsi_Host *host, long offset)
-{
- struct isp1020_hostdata *h = (struct isp1020_hostdata *)host->hostdata;
- if (h->memaddr)
- return readw(h->memaddr + offset);
- else
- return inw(host->io_port + offset);
-}
-
-static inline void isp_outw(u_short val, struct Scsi_Host *host, long offset)
-{
- struct isp1020_hostdata *h = (struct isp1020_hostdata *)host->hostdata;
- if (h->memaddr)
- writew(val, h->memaddr + offset);
- else
- outw(val, host->io_port + offset);
-}
-
-static inline void isp1020_enable_irqs(struct Scsi_Host *host)
-{
- isp_outw(ISP_EN_INT|ISP_EN_RISC, host, PCI_INTF_CTL);
-}
-
-
-static inline void isp1020_disable_irqs(struct Scsi_Host *host)
-{
- isp_outw(0x0, host, PCI_INTF_CTL);
-}
-
-
-static int isp1020_detect(Scsi_Host_Template *tmpt)
-{
- int hosts = 0;
- struct Scsi_Host *host;
- struct isp1020_hostdata *hostdata;
- struct pci_dev *pdev = NULL;
-
- ENTER("isp1020_detect");
-
- tmpt->proc_name = "isp1020";
-
- while ((pdev = pci_find_device(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020, pdev)))
- {
- if (pci_enable_device(pdev))
- continue;
-
- host = scsi_register(tmpt, sizeof(struct isp1020_hostdata));
- if (!host)
- continue;
-
- hostdata = (struct isp1020_hostdata *) host->hostdata;
-
- memset(hostdata, 0, sizeof(struct isp1020_hostdata));
-
- hostdata->pci_dev = pdev;
-
- if (isp1020_init(host))
- goto fail_and_unregister;
-
- if (isp1020_reset_hardware(host)
-#if USE_NVRAM_DEFAULTS
- || isp1020_get_defaults(host)
-#else
- || isp1020_set_defaults(host)
-#endif /* USE_NVRAM_DEFAULTS */
- || isp1020_load_parameters(host)) {
- goto fail_uninit;
- }
-
- host->this_id = hostdata->host_param.initiator_scsi_id;
- host->max_sectors = 64;
-
- if (request_irq(host->irq, do_isp1020_intr_handler, SA_INTERRUPT | SA_SHIRQ,
- "qlogicisp", host))
- {
- printk("qlogicisp : interrupt %d already in use\n",
- host->irq);
- goto fail_uninit;
- }
-
- isp_outw(0x0, host, PCI_SEMAPHORE);
- isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
- isp1020_enable_irqs(host);
-
- hosts++;
- continue;
-
- fail_uninit:
- iounmap(hostdata->memaddr);
- release_region(host->io_port, 0xff);
- fail_and_unregister:
- if (hostdata->res_cpu)
- pci_free_consistent(hostdata->pci_dev,
- QSIZE(RES_QUEUE_LEN),
- hostdata->res_cpu,
- hostdata->res_dma);
- if (hostdata->req_cpu)
- pci_free_consistent(hostdata->pci_dev,
- QSIZE(QLOGICISP_REQ_QUEUE_LEN),
- hostdata->req_cpu,
- hostdata->req_dma);
- scsi_unregister(host);
- }
-
- LEAVE("isp1020_detect");
-
- return hosts;
-}
-
-
-static int isp1020_release(struct Scsi_Host *host)
-{
- struct isp1020_hostdata *hostdata;
-
- ENTER("isp1020_release");
-
- hostdata = (struct isp1020_hostdata *) host->hostdata;
-
- isp_outw(0x0, host, PCI_INTF_CTL);
- free_irq(host->irq, host);
-
- iounmap(hostdata->memaddr);
-
- release_region(host->io_port, 0xff);
-
- LEAVE("isp1020_release");
-
- return 0;
-}
-
-
-static const char *isp1020_info(struct Scsi_Host *host)
-{
- static char buf[80];
- struct isp1020_hostdata *hostdata;
-
- ENTER("isp1020_info");
-
- hostdata = (struct isp1020_hostdata *) host->hostdata;
- sprintf(buf,
- "QLogic ISP1020 SCSI on PCI bus %02x device %02x irq %d %s base 0x%lx",
- hostdata->pci_dev->bus->number, hostdata->pci_dev->devfn, host->irq,
- (hostdata->memaddr ? "MEM" : "I/O"),
- (hostdata->memaddr ? (unsigned long)hostdata->memaddr : host->io_port));
-
- LEAVE("isp1020_info");
-
- return buf;
-}
-
-
-/*
- * The middle SCSI layer ensures that queuecommand never gets invoked
- * concurrently with itself or the interrupt handler (though the
- * interrupt handler may call this routine as part of
- * request-completion handling).
- */
-static int isp1020_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
-{
- int i, n, num_free;
- u_int in_ptr, out_ptr;
- struct dataseg * ds;
- struct scatterlist *sg;
- struct Command_Entry *cmd;
- struct Continuation_Entry *cont;
- struct Scsi_Host *host;
- struct isp1020_hostdata *hostdata;
- dma_addr_t dma_addr;
-
- ENTER("isp1020_queuecommand");
-
- host = Cmnd->device->host;
- hostdata = (struct isp1020_hostdata *) host->hostdata;
- Cmnd->scsi_done = done;
-
- DEBUG(isp1020_print_scsi_cmd(Cmnd));
-
- out_ptr = isp_inw(host, + MBOX4);
- in_ptr = hostdata->req_in_ptr;
-
- DEBUG(printk("qlogicisp : request queue depth %d\n",
- REQ_QUEUE_DEPTH(in_ptr, out_ptr)));
-
- cmd = (struct Command_Entry *) &hostdata->req_cpu[in_ptr];
- in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN;
- if (in_ptr == out_ptr) {
- printk("qlogicisp : request queue overflow\n");
- return 1;
- }
-
- if (hostdata->send_marker) {
- struct Marker_Entry *marker;
-
- TRACE("queue marker", in_ptr, 0);
-
- DEBUG(printk("qlogicisp : adding marker entry\n"));
- marker = (struct Marker_Entry *) cmd;
- memset(marker, 0, sizeof(struct Marker_Entry));
-
- marker->hdr.entry_type = ENTRY_MARKER;
- marker->hdr.entry_cnt = 1;
- marker->modifier = SYNC_ALL;
-
- hostdata->send_marker = 0;
-
- if (((in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN) == out_ptr) {
- isp_outw(in_ptr, host, MBOX4);
- hostdata->req_in_ptr = in_ptr;
- printk("qlogicisp : request queue overflow\n");
- return 1;
- }
- cmd = (struct Command_Entry *) &hostdata->req_cpu[in_ptr];
- in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN;
- }
-
- TRACE("queue command", in_ptr, Cmnd);
-
- memset(cmd, 0, sizeof(struct Command_Entry));
-
- cmd->hdr.entry_type = ENTRY_COMMAND;
- cmd->hdr.entry_cnt = 1;
-
- cmd->target_lun = Cmnd->device->lun;
- cmd->target_id = Cmnd->device->id;
- cmd->cdb_length = cpu_to_le16(Cmnd->cmd_len);
- cmd->control_flags = cpu_to_le16(CFLAG_READ | CFLAG_WRITE);
- cmd->time_out = cpu_to_le16(30);
-
- memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len);
-
- if (Cmnd->use_sg) {
- int sg_count;
-
- sg = (struct scatterlist *) Cmnd->request_buffer;
- ds = cmd->dataseg;
-
- sg_count = pci_map_sg(hostdata->pci_dev, sg, Cmnd->use_sg,
- Cmnd->sc_data_direction);
-
- cmd->segment_cnt = cpu_to_le16(sg_count);
-
- /* fill in first four sg entries: */
- n = sg_count;
- if (n > IOCB_SEGS)
- n = IOCB_SEGS;
- for (i = 0; i < n; i++) {
- dma_addr = sg_dma_address(sg);
- ds[i].d_base = cpu_to_le32((u32) dma_addr);
-#ifdef CONFIG_QL_ISP_A64
- ds[i].d_base_hi = cpu_to_le32((u32) (dma_addr>>32));
-#endif /* CONFIG_QL_ISP_A64 */
- ds[i].d_count = cpu_to_le32(sg_dma_len(sg));
- ++sg;
- }
- sg_count -= IOCB_SEGS;
-
- while (sg_count > 0) {
- ++cmd->hdr.entry_cnt;
- cont = (struct Continuation_Entry *)
- &hostdata->req_cpu[in_ptr];
- in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN;
- if (in_ptr == out_ptr) {
- printk("isp1020: unexpected request queue "
- "overflow\n");
- return 1;
- }
- TRACE("queue continuation", in_ptr, 0);
- cont->hdr.entry_type = ENTRY_CONTINUATION;
- cont->hdr.entry_cnt = 0;
- cont->hdr.sys_def_1 = 0;
- cont->hdr.flags = 0;
-#ifndef CONFIG_QL_ISP_A64
- cont->reserved = 0;
-#endif
- ds = cont->dataseg;
- n = sg_count;
- if (n > CONTINUATION_SEGS)
- n = CONTINUATION_SEGS;
- for (i = 0; i < n; ++i) {
- dma_addr = sg_dma_address(sg);
- ds[i].d_base = cpu_to_le32((u32) dma_addr);
-#ifdef CONFIG_QL_ISP_A64
- ds[i].d_base_hi = cpu_to_le32((u32)(dma_addr>>32));
-#endif /* CONFIG_QL_ISP_A64 */
- ds[i].d_count = cpu_to_le32(sg_dma_len(sg));
- ++sg;
- }
- sg_count -= n;
- }
- } else if (Cmnd->request_bufflen) {
- /*Cmnd->SCp.ptr = (char *)(unsigned long)*/
- dma_addr = pci_map_single(hostdata->pci_dev,
- Cmnd->request_buffer,
- Cmnd->request_bufflen,
- Cmnd->sc_data_direction);
- Cmnd->SCp.ptr = (char *)(unsigned long) dma_addr;
-
- cmd->dataseg[0].d_base =
- cpu_to_le32((u32) dma_addr);
-#ifdef CONFIG_QL_ISP_A64
- cmd->dataseg[0].d_base_hi =
- cpu_to_le32((u32) (dma_addr>>32));
-#endif /* CONFIG_QL_ISP_A64 */
- cmd->dataseg[0].d_count =
- cpu_to_le32((u32)Cmnd->request_bufflen);
- cmd->segment_cnt = cpu_to_le16(1);
- } else {
- cmd->dataseg[0].d_base = 0;
-#ifdef CONFIG_QL_ISP_A64
- cmd->dataseg[0].d_base_hi = 0;
-#endif /* CONFIG_QL_ISP_A64 */
- cmd->dataseg[0].d_count = 0;
- cmd->segment_cnt = cpu_to_le16(1); /* Shouldn't this be 0? */
- }
-
- /* Committed, record Scsi_Cmd so we can find it later. */
- cmd->handle = in_ptr;
- hostdata->cmd_slots[in_ptr] = Cmnd;
-
- isp_outw(in_ptr, host, MBOX4);
- hostdata->req_in_ptr = in_ptr;
-
- num_free = QLOGICISP_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
- host->can_queue = host->host_busy + num_free;
- host->sg_tablesize = QLOGICISP_MAX_SG(num_free);
-
- LEAVE("isp1020_queuecommand");
-
- return 0;
-}
-
-
-#define ASYNC_EVENT_INTERRUPT 0x01
-
-irqreturn_t do_isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct Scsi_Host *host = dev_id;
- unsigned long flags;
-
- spin_lock_irqsave(host->host_lock, flags);
- isp1020_intr_handler(irq, dev_id, regs);
- spin_unlock_irqrestore(host->host_lock, flags);
-
- return IRQ_HANDLED;
-}
-
-void isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
- Scsi_Cmnd *Cmnd;
- struct Status_Entry *sts;
- struct Scsi_Host *host = dev_id;
- struct isp1020_hostdata *hostdata;
- u_int in_ptr, out_ptr;
- u_short status;
-
- ENTER_INTR("isp1020_intr_handler");
-
- hostdata = (struct isp1020_hostdata *) host->hostdata;
-
- DEBUG_INTR(printk("qlogicisp : interrupt on line %d\n", irq));
-
- if (!(isp_inw(host, PCI_INTF_STS) & 0x04)) {
- /* spurious interrupts can happen legally */
- DEBUG_INTR(printk("qlogicisp: got spurious interrupt\n"));
- return;
- }
- in_ptr = isp_inw(host, MBOX5);
- isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
-
- if ((isp_inw(host, PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) {
- status = isp_inw(host, MBOX0);
-
- DEBUG_INTR(printk("qlogicisp : mbox completion status: %x\n",
- status));
-
- switch (status) {
- case ASYNC_SCSI_BUS_RESET:
- case EXECUTION_TIMEOUT_RESET:
- hostdata->send_marker = 1;
- break;
- case INVALID_COMMAND:
- case HOST_INTERFACE_ERROR:
- case COMMAND_ERROR:
- case COMMAND_PARAM_ERROR:
- printk("qlogicisp : bad mailbox return status\n");
- break;
- }
- isp_outw(0x0, host, PCI_SEMAPHORE);
- }
- out_ptr = hostdata->res_out_ptr;
-
- DEBUG_INTR(printk("qlogicisp : response queue update\n"));
- DEBUG_INTR(printk("qlogicisp : response queue depth %d\n",
- QUEUE_DEPTH(in_ptr, out_ptr, RES_QUEUE_LEN)));
-
- while (out_ptr != in_ptr) {
- u_int cmd_slot;
-
- sts = (struct Status_Entry *) &hostdata->res_cpu[out_ptr];
- out_ptr = (out_ptr + 1) & RES_QUEUE_LEN;
-
- cmd_slot = sts->handle;
- Cmnd = hostdata->cmd_slots[cmd_slot];
- hostdata->cmd_slots[cmd_slot] = NULL;
-
- TRACE("done", out_ptr, Cmnd);
-
- if (le16_to_cpu(sts->completion_status) == CS_RESET_OCCURRED
- || le16_to_cpu(sts->completion_status) == CS_ABORTED
- || (le16_to_cpu(sts->status_flags) & STF_BUS_RESET))
- hostdata->send_marker = 1;
-
- if (le16_to_cpu(sts->state_flags) & SF_GOT_SENSE)
- memcpy(Cmnd->sense_buffer, sts->req_sense_data,
- sizeof(Cmnd->sense_buffer));
-
- DEBUG_INTR(isp1020_print_status_entry(sts));
-
- if (sts->hdr.entry_type == ENTRY_STATUS)
- Cmnd->result = isp1020_return_status(sts);
- else
- Cmnd->result = DID_ERROR << 16;
-
- if (Cmnd->use_sg)
- pci_unmap_sg(hostdata->pci_dev,
- (struct scatterlist *)Cmnd->buffer,
- Cmnd->use_sg,
- Cmnd->sc_data_direction);
- else if (Cmnd->request_bufflen)
- pci_unmap_single(hostdata->pci_dev,
-#ifdef CONFIG_QL_ISP_A64
- (dma_addr_t)((long)Cmnd->SCp.ptr),
-#else
- (u32)((long)Cmnd->SCp.ptr),
-#endif
- Cmnd->request_bufflen,
- Cmnd->sc_data_direction);
-
- isp_outw(out_ptr, host, MBOX5);
- (*Cmnd->scsi_done)(Cmnd);
- }
- hostdata->res_out_ptr = out_ptr;
-
- LEAVE_INTR("isp1020_intr_handler");
-}
-
-
-static int isp1020_return_status(struct Status_Entry *sts)
-{
- int host_status = DID_ERROR;
-#if DEBUG_ISP1020_INTR
- static char *reason[] = {
- "DID_OK",
- "DID_NO_CONNECT",
- "DID_BUS_BUSY",
- "DID_TIME_OUT",
- "DID_BAD_TARGET",
- "DID_ABORT",
- "DID_PARITY",
- "DID_ERROR",
- "DID_RESET",
- "DID_BAD_INTR"
- };
-#endif /* DEBUG_ISP1020_INTR */
-
- ENTER("isp1020_return_status");
-
- DEBUG(printk("qlogicisp : completion status = 0x%04x\n",
- le16_to_cpu(sts->completion_status)));
-
- switch(le16_to_cpu(sts->completion_status)) {
- case CS_COMPLETE:
- host_status = DID_OK;
- break;
- case CS_INCOMPLETE:
- if (!(le16_to_cpu(sts->state_flags) & SF_GOT_BUS))
- host_status = DID_NO_CONNECT;
- else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_TARGET))
- host_status = DID_BAD_TARGET;
- else if (!(le16_to_cpu(sts->state_flags) & SF_SENT_CDB))
- host_status = DID_ERROR;
- else if (!(le16_to_cpu(sts->state_flags) & SF_TRANSFERRED_DATA))
- host_status = DID_ERROR;
- else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_STATUS))
- host_status = DID_ERROR;
- else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_SENSE))
- host_status = DID_ERROR;
- break;
- case CS_DMA_ERROR:
- case CS_TRANSPORT_ERROR:
- host_status = DID_ERROR;
- break;
- case CS_RESET_OCCURRED:
- host_status = DID_RESET;
- break;
- case CS_ABORTED:
- host_status = DID_ABORT;
- break;
- case CS_TIMEOUT:
- host_status = DID_TIME_OUT;
- break;
- case CS_DATA_OVERRUN:
- case CS_COMMAND_OVERRUN:
- case CS_STATUS_OVERRUN:
- case CS_BAD_MESSAGE:
- case CS_NO_MESSAGE_OUT:
- case CS_EXT_ID_FAILED:
- case CS_IDE_MSG_FAILED:
- case CS_ABORT_MSG_FAILED:
- case CS_NOP_MSG_FAILED:
- case CS_PARITY_ERROR_MSG_FAILED:
- case CS_DEVICE_RESET_MSG_FAILED:
- case CS_ID_MSG_FAILED:
- case CS_UNEXP_BUS_FREE:
- host_status = DID_ERROR;
- break;
- case CS_DATA_UNDERRUN:
- host_status = DID_OK;
- break;
- default:
- printk("qlogicisp : unknown completion status 0x%04x\n",
- le16_to_cpu(sts->completion_status));
- host_status = DID_ERROR;
- break;
- }
-
- DEBUG_INTR(printk("qlogicisp : host status (%s) scsi status %x\n",
- reason[host_status], le16_to_cpu(sts->scsi_status)));
-
- LEAVE("isp1020_return_status");
-
- return (le16_to_cpu(sts->scsi_status) & STATUS_MASK) | (host_status << 16);
-}
-
-
-static int isp1020_biosparam(struct scsi_device *sdev, struct block_device *n,
- sector_t capacity, int ip[])
-{
- int size = capacity;
-
- ENTER("isp1020_biosparam");
-
- ip[0] = 64;
- ip[1] = 32;
- ip[2] = size >> 11;
- if (ip[2] > 1024) {
- ip[0] = 255;
- ip[1] = 63;
- ip[2] = size / (ip[0] * ip[1]);
-#if 0
- if (ip[2] > 1023)
- ip[2] = 1023;
-#endif
- }
-
- LEAVE("isp1020_biosparam");
-
- return 0;
-}
-
-
-static int isp1020_reset_hardware(struct Scsi_Host *host)
-{
- u_short param[6];
- int loop_count;
-
- ENTER("isp1020_reset_hardware");
-
- isp_outw(ISP_RESET, host, PCI_INTF_CTL);
- udelay(100);
- isp_outw(HCCR_RESET, host, HOST_HCCR);
- udelay(100);
- isp_outw(HCCR_RELEASE, host, HOST_HCCR);
- isp_outw(HCCR_BIOS_DISABLE, host, HOST_HCCR);
-
- loop_count = DEFAULT_LOOP_COUNT;
- while (--loop_count && isp_inw(host, HOST_HCCR) == RISC_BUSY) {
- barrier();
- cpu_relax();
- }
- if (!loop_count)
- printk("qlogicisp: reset_hardware loop timeout\n");
-
- isp_outw(0, host, ISP_CFG1);
-
-#if DEBUG_ISP1020
- printk("qlogicisp : mbox 0 0x%04x \n", isp_inw(host, MBOX0));
- printk("qlogicisp : mbox 1 0x%04x \n", isp_inw(host, MBOX1));
- printk("qlogicisp : mbox 2 0x%04x \n", isp_inw(host, MBOX2));
- printk("qlogicisp : mbox 3 0x%04x \n", isp_inw(host, MBOX3));
- printk("qlogicisp : mbox 4 0x%04x \n", isp_inw(host, MBOX4));
- printk("qlogicisp : mbox 5 0x%04x \n", isp_inw(host, MBOX5));
-#endif /* DEBUG_ISP1020 */
-
- param[0] = MBOX_NO_OP;
- isp1020_mbox_command(host, param);
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : NOP test failed\n");
- return 1;
- }
-
- DEBUG(printk("qlogicisp : loading risc ram\n"));
-
-#if RELOAD_FIRMWARE
- for (loop_count = 0; loop_count < risc_code_length01; loop_count++) {
- param[0] = MBOX_WRITE_RAM_WORD;
- param[1] = risc_code_addr01 + loop_count;
- param[2] = risc_code01[loop_count];
- isp1020_mbox_command(host, param);
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : firmware load failure at %d\n",
- loop_count);
- return 1;
- }
- }
-#endif /* RELOAD_FIRMWARE */
-
- DEBUG(printk("qlogicisp : verifying checksum\n"));
-
- param[0] = MBOX_VERIFY_CHECKSUM;
- param[1] = risc_code_addr01;
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : ram checksum failure\n");
- return 1;
- }
-
- DEBUG(printk("qlogicisp : executing firmware\n"));
-
- param[0] = MBOX_EXEC_FIRMWARE;
- param[1] = risc_code_addr01;
-
- isp1020_mbox_command(host, param);
-
- param[0] = MBOX_ABOUT_FIRMWARE;
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : about firmware failure\n");
- return 1;
- }
-
- DEBUG(printk("qlogicisp : firmware major revision %d\n", param[1]));
- DEBUG(printk("qlogicisp : firmware minor revision %d\n", param[2]));
-
- LEAVE("isp1020_reset_hardware");
-
- return 0;
-}
-
-
-static int isp1020_init(struct Scsi_Host *sh)
-{
- u_long io_base, mem_base, io_flags, mem_flags;
- struct isp1020_hostdata *hostdata;
- u_char revision;
- u_int irq;
- u_short command;
- struct pci_dev *pdev;
-
- ENTER("isp1020_init");
-
- hostdata = (struct isp1020_hostdata *) sh->hostdata;
- pdev = hostdata->pci_dev;
-
- if (pci_read_config_word(pdev, PCI_COMMAND, &command)
- || pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision))
- {
- printk("qlogicisp : error reading PCI configuration\n");
- return 1;
- }
-
- io_base = pci_resource_start(pdev, 0);
- mem_base = pci_resource_start(pdev, 1);
- io_flags = pci_resource_flags(pdev, 0);
- mem_flags = pci_resource_flags(pdev, 1);
- irq = pdev->irq;
-
- if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) {
- printk("qlogicisp : 0x%04x is not QLogic vendor ID\n",
- pdev->vendor);
- return 1;
- }
-
- if (pdev->device != PCI_DEVICE_ID_QLOGIC_ISP1020) {
- printk("qlogicisp : 0x%04x does not match ISP1020 device id\n",
- pdev->device);
- return 1;
- }
-
-#ifdef __alpha__
- /* Force ALPHA to use bus I/O and not bus MEM.
- This is to avoid having to use HAE_MEM registers,
- which is broken on some platforms and with SMP. */
- command &= ~PCI_COMMAND_MEMORY;
-#endif
-
- sh->io_port = io_base;
-
- if (!request_region(sh->io_port, 0xff, "qlogicisp")) {
- printk("qlogicisp : i/o region 0x%lx-0x%lx already "
- "in use\n",
- sh->io_port, sh->io_port + 0xff);
- return 1;
- }
-
- if ((command & PCI_COMMAND_MEMORY) &&
- ((mem_flags & 1) == 0)) {
- hostdata->memaddr = ioremap(mem_base, PAGE_SIZE);
- if (!hostdata->memaddr) {
- printk("qlogicisp : i/o remapping failed.\n");
- goto out_release;
- }
- } else {
- if (command & PCI_COMMAND_IO && (io_flags & 3) != 1) {
- printk("qlogicisp : i/o mapping is disabled\n");
- goto out_release;
- }
- hostdata->memaddr = NULL; /* zero to signify no i/o mapping */
- mem_base = 0;
- }
-
- if (revision != ISP1020_REV_ID)
- printk("qlogicisp : new isp1020 revision ID (%d)\n", revision);
-
- if (isp_inw(sh, PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC
- || isp_inw(sh, PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020)
- {
- printk("qlogicisp : can't decode %s address space 0x%lx\n",
- (io_base ? "I/O" : "MEM"),
- (io_base ? io_base : mem_base));
- goto out_unmap;
- }
-
- hostdata->revision = revision;
-
- sh->irq = irq;
- sh->max_id = MAX_TARGETS;
- sh->max_lun = MAX_LUNS;
-
- hostdata->res_cpu = pci_alloc_consistent(hostdata->pci_dev,
- QSIZE(RES_QUEUE_LEN),
- &hostdata->res_dma);
- if (hostdata->res_cpu == NULL) {
- printk("qlogicisp : can't allocate response queue\n");
- goto out_unmap;
- }
-
- hostdata->req_cpu = pci_alloc_consistent(hostdata->pci_dev,
- QSIZE(QLOGICISP_REQ_QUEUE_LEN),
- &hostdata->req_dma);
- if (hostdata->req_cpu == NULL) {
- pci_free_consistent(hostdata->pci_dev,
- QSIZE(RES_QUEUE_LEN),
- hostdata->res_cpu,
- hostdata->res_dma);
- printk("qlogicisp : can't allocate request queue\n");
- goto out_unmap;
- }
-
- pci_set_master(pdev);
-
- LEAVE("isp1020_init");
-
- return 0;
-
-out_unmap:
- iounmap(hostdata->memaddr);
-out_release:
- release_region(sh->io_port, 0xff);
- return 1;
-}
-
-
-#if USE_NVRAM_DEFAULTS
-
-static int isp1020_get_defaults(struct Scsi_Host *host)
-{
- int i;
- u_short value;
- struct isp1020_hostdata *hostdata =
- (struct isp1020_hostdata *) host->hostdata;
-
- ENTER("isp1020_get_defaults");
-
- if (!isp1020_verify_nvram(host)) {
- printk("qlogicisp : nvram checksum failure\n");
- printk("qlogicisp : attempting to use default parameters\n");
- return isp1020_set_defaults(host);
- }
-
- value = isp1020_read_nvram_word(host, 2);
- hostdata->host_param.fifo_threshold = (value >> 8) & 0x03;
- hostdata->host_param.host_adapter_enable = (value >> 11) & 0x01;
- hostdata->host_param.initiator_scsi_id = (value >> 12) & 0x0f;
-
- value = isp1020_read_nvram_word(host, 3);
- hostdata->host_param.bus_reset_delay = value & 0xff;
- hostdata->host_param.retry_count = value >> 8;
-
- value = isp1020_read_nvram_word(host, 4);
- hostdata->host_param.retry_delay = value & 0xff;
- hostdata->host_param.async_data_setup_time = (value >> 8) & 0x0f;
- hostdata->host_param.req_ack_active_negation = (value >> 12) & 0x01;
- hostdata->host_param.data_line_active_negation = (value >> 13) & 0x01;
- hostdata->host_param.data_dma_burst_enable = (value >> 14) & 0x01;
- hostdata->host_param.command_dma_burst_enable = (value >> 15);
-
- value = isp1020_read_nvram_word(host, 5);
- hostdata->host_param.tag_aging = value & 0xff;
-
- value = isp1020_read_nvram_word(host, 6);
- hostdata->host_param.selection_timeout = value & 0xffff;
-
- value = isp1020_read_nvram_word(host, 7);
- hostdata->host_param.max_queue_depth = value & 0xffff;
-
-#if DEBUG_ISP1020_SETUP
- printk("qlogicisp : fifo threshold=%d\n",
- hostdata->host_param.fifo_threshold);
- printk("qlogicisp : initiator scsi id=%d\n",
- hostdata->host_param.initiator_scsi_id);
- printk("qlogicisp : bus reset delay=%d\n",
- hostdata->host_param.bus_reset_delay);
- printk("qlogicisp : retry count=%d\n",
- hostdata->host_param.retry_count);
- printk("qlogicisp : retry delay=%d\n",
- hostdata->host_param.retry_delay);
- printk("qlogicisp : async data setup time=%d\n",
- hostdata->host_param.async_data_setup_time);
- printk("qlogicisp : req/ack active negation=%d\n",
- hostdata->host_param.req_ack_active_negation);
- printk("qlogicisp : data line active negation=%d\n",
- hostdata->host_param.data_line_active_negation);
- printk("qlogicisp : data DMA burst enable=%d\n",
- hostdata->host_param.data_dma_burst_enable);
- printk("qlogicisp : command DMA burst enable=%d\n",
- hostdata->host_param.command_dma_burst_enable);
- printk("qlogicisp : tag age limit=%d\n",
- hostdata->host_param.tag_aging);
- printk("qlogicisp : selection timeout limit=%d\n",
- hostdata->host_param.selection_timeout);
- printk("qlogicisp : max queue depth=%d\n",
- hostdata->host_param.max_queue_depth);
-#endif /* DEBUG_ISP1020_SETUP */
-
- for (i = 0; i < MAX_TARGETS; i++) {
-
- value = isp1020_read_nvram_word(host, 14 + i * 3);
- hostdata->dev_param[i].device_flags = value & 0xff;
- hostdata->dev_param[i].execution_throttle = value >> 8;
-
- value = isp1020_read_nvram_word(host, 15 + i * 3);
- hostdata->dev_param[i].synchronous_period = value & 0xff;
- hostdata->dev_param[i].synchronous_offset = (value >> 8) & 0x0f;
- hostdata->dev_param[i].device_enable = (value >> 12) & 0x01;
-
-#if DEBUG_ISP1020_SETUP
- printk("qlogicisp : target 0x%02x\n", i);
- printk("qlogicisp : device flags=0x%02x\n",
- hostdata->dev_param[i].device_flags);
- printk("qlogicisp : execution throttle=%d\n",
- hostdata->dev_param[i].execution_throttle);
- printk("qlogicisp : synchronous period=%d\n",
- hostdata->dev_param[i].synchronous_period);
- printk("qlogicisp : synchronous offset=%d\n",
- hostdata->dev_param[i].synchronous_offset);
- printk("qlogicisp : device enable=%d\n",
- hostdata->dev_param[i].device_enable);
-#endif /* DEBUG_ISP1020_SETUP */
- }
-
- LEAVE("isp1020_get_defaults");
-
- return 0;
-}
-
-
-#define ISP1020_NVRAM_LEN 0x40
-#define ISP1020_NVRAM_SIG1 0x5349
-#define ISP1020_NVRAM_SIG2 0x2050
-
-static int isp1020_verify_nvram(struct Scsi_Host *host)
-{
- int i;
- u_short value;
- u_char checksum = 0;
-
- for (i = 0; i < ISP1020_NVRAM_LEN; i++) {
- value = isp1020_read_nvram_word(host, i);
-
- switch (i) {
- case 0:
- if (value != ISP1020_NVRAM_SIG1) return 0;
- break;
- case 1:
- if (value != ISP1020_NVRAM_SIG2) return 0;
- break;
- case 2:
- if ((value & 0xff) != 0x02) return 0;
- break;
- }
- checksum += value & 0xff;
- checksum += value >> 8;
- }
-
- return (checksum == 0);
-}
-
-#define NVRAM_DELAY() udelay(2) /* 2 microsecond delay */
-
-
-u_short isp1020_read_nvram_word(struct Scsi_Host *host, u_short byte)
-{
- int i;
- u_short value, output, input;
-
- byte &= 0x3f; byte |= 0x0180;
-
- for (i = 8; i >= 0; i--) {
- output = ((byte >> i) & 0x1) ? 0x4 : 0x0;
- isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY();
- isp_outw(output | 0x3, host, PCI_NVRAM); NVRAM_DELAY();
- isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY();
- }
-
- for (i = 0xf, value = 0; i >= 0; i--) {
- value <<= 1;
- isp_outw(0x3, host, PCI_NVRAM); NVRAM_DELAY();
- input = isp_inw(host, PCI_NVRAM); NVRAM_DELAY();
- isp_outw(0x2, host, PCI_NVRAM); NVRAM_DELAY();
- if (input & 0x8) value |= 1;
- }
-
- isp_outw(0x0, host, PCI_NVRAM); NVRAM_DELAY();
-
- return value;
-}
-
-#endif /* USE_NVRAM_DEFAULTS */
-
-
-static int isp1020_set_defaults(struct Scsi_Host *host)
-{
- struct isp1020_hostdata *hostdata =
- (struct isp1020_hostdata *) host->hostdata;
- int i;
-
- ENTER("isp1020_set_defaults");
-
- hostdata->host_param.fifo_threshold = 2;
- hostdata->host_param.host_adapter_enable = 1;
- hostdata->host_param.initiator_scsi_id = 7;
- hostdata->host_param.bus_reset_delay = 3;
- hostdata->host_param.retry_count = 0;
- hostdata->host_param.retry_delay = 1;
- hostdata->host_param.async_data_setup_time = 6;
- hostdata->host_param.req_ack_active_negation = 1;
- hostdata->host_param.data_line_active_negation = 1;
- hostdata->host_param.data_dma_burst_enable = 1;
- hostdata->host_param.command_dma_burst_enable = 1;
- hostdata->host_param.tag_aging = 8;
- hostdata->host_param.selection_timeout = 250;
- hostdata->host_param.max_queue_depth = 256;
-
- for (i = 0; i < MAX_TARGETS; i++) {
- hostdata->dev_param[i].device_flags = 0xfd;
- hostdata->dev_param[i].execution_throttle = 16;
- hostdata->dev_param[i].synchronous_period = 25;
- hostdata->dev_param[i].synchronous_offset = 12;
- hostdata->dev_param[i].device_enable = 1;
- }
-
- LEAVE("isp1020_set_defaults");
-
- return 0;
-}
-
-
-static int isp1020_load_parameters(struct Scsi_Host *host)
-{
- int i, k;
-#ifdef CONFIG_QL_ISP_A64
- u_long queue_addr;
- u_short param[8];
-#else
- u_int queue_addr;
- u_short param[6];
-#endif
- u_short isp_cfg1, hwrev;
- struct isp1020_hostdata *hostdata =
- (struct isp1020_hostdata *) host->hostdata;
-
- ENTER("isp1020_load_parameters");
-
- hwrev = isp_inw(host, ISP_CFG0) & ISP_CFG0_HWMSK;
- isp_cfg1 = ISP_CFG1_F64 | ISP_CFG1_BENAB;
- if (hwrev == ISP_CFG0_1040A) {
- /* Busted fifo, says mjacob. */
- isp_cfg1 &= ISP_CFG1_BENAB;
- }
-
- isp_outw(isp_inw(host, ISP_CFG1) | isp_cfg1, host, ISP_CFG1);
- isp_outw(isp_inw(host, CDMA_CONF) | DMA_CONF_BENAB, host, CDMA_CONF);
- isp_outw(isp_inw(host, DDMA_CONF) | DMA_CONF_BENAB, host, DDMA_CONF);
-
- param[0] = MBOX_SET_INIT_SCSI_ID;
- param[1] = hostdata->host_param.initiator_scsi_id;
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : set initiator id failure\n");
- return 1;
- }
-
- param[0] = MBOX_SET_RETRY_COUNT;
- param[1] = hostdata->host_param.retry_count;
- param[2] = hostdata->host_param.retry_delay;
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : set retry count failure\n");
- return 1;
- }
-
- param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
- param[1] = hostdata->host_param.async_data_setup_time;
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : async data setup time failure\n");
- return 1;
- }
-
- param[0] = MBOX_SET_ACTIVE_NEG_STATE;
- param[1] = (hostdata->host_param.req_ack_active_negation << 4)
- | (hostdata->host_param.data_line_active_negation << 5);
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : set active negation state failure\n");
- return 1;
- }
-
- param[0] = MBOX_SET_PCI_CONTROL_PARAMS;
- param[1] = hostdata->host_param.data_dma_burst_enable << 1;
- param[2] = hostdata->host_param.command_dma_burst_enable << 1;
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : set pci control parameter failure\n");
- return 1;
- }
-
- param[0] = MBOX_SET_TAG_AGE_LIMIT;
- param[1] = hostdata->host_param.tag_aging;
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : set tag age limit failure\n");
- return 1;
- }
-
- param[0] = MBOX_SET_SELECT_TIMEOUT;
- param[1] = hostdata->host_param.selection_timeout;
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : set selection timeout failure\n");
- return 1;
- }
-
- for (i = 0; i < MAX_TARGETS; i++) {
-
- if (!hostdata->dev_param[i].device_enable)
- continue;
-
- param[0] = MBOX_SET_TARGET_PARAMS;
- param[1] = i << 8;
- param[2] = hostdata->dev_param[i].device_flags << 8;
- param[3] = (hostdata->dev_param[i].synchronous_offset << 8)
- | hostdata->dev_param[i].synchronous_period;
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : set target parameter failure\n");
- return 1;
- }
-
- for (k = 0; k < MAX_LUNS; k++) {
-
- param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
- param[1] = (i << 8) | k;
- param[2] = hostdata->host_param.max_queue_depth;
- param[3] = hostdata->dev_param[i].execution_throttle;
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : set device queue "
- "parameter failure\n");
- return 1;
- }
- }
- }
-
- queue_addr = hostdata->res_dma;
-#ifdef CONFIG_QL_ISP_A64
- param[0] = MBOX_CMD_INIT_RESPONSE_QUEUE_64;
-#else
- param[0] = MBOX_INIT_RES_QUEUE;
-#endif
- param[1] = RES_QUEUE_LEN + 1;
- param[2] = (u_short) (queue_addr >> 16);
- param[3] = (u_short) (queue_addr & 0xffff);
- param[4] = 0;
- param[5] = 0;
-#ifdef CONFIG_QL_ISP_A64
- param[6] = (u_short) (queue_addr >> 48);
- param[7] = (u_short) (queue_addr >> 32);
-#endif
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : set response queue failure\n");
- return 1;
- }
-
- queue_addr = hostdata->req_dma;
-#ifdef CONFIG_QL_ISP_A64
- param[0] = MBOX_CMD_INIT_REQUEST_QUEUE_64;
-#else
- param[0] = MBOX_INIT_REQ_QUEUE;
-#endif
- param[1] = QLOGICISP_REQ_QUEUE_LEN + 1;
- param[2] = (u_short) (queue_addr >> 16);
- param[3] = (u_short) (queue_addr & 0xffff);
- param[4] = 0;
-
-#ifdef CONFIG_QL_ISP_A64
- param[5] = 0;
- param[6] = (u_short) (queue_addr >> 48);
- param[7] = (u_short) (queue_addr >> 32);
-#endif
-
- isp1020_mbox_command(host, param);
-
- if (param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicisp : set request queue failure\n");
- return 1;
- }
-
- LEAVE("isp1020_load_parameters");
-
- return 0;
-}
-
-
-/*
- * currently, this is only called during initialization or abort/reset,
- * at which times interrupts are disabled, so polling is OK, I guess...
- */
-static int isp1020_mbox_command(struct Scsi_Host *host, u_short param[])
-{
- int loop_count;
-
- if (mbox_param[param[0]] == 0)
- return 1;
-
- loop_count = DEFAULT_LOOP_COUNT;
- while (--loop_count && isp_inw(host, HOST_HCCR) & 0x0080) {
- barrier();
- cpu_relax();
- }
- if (!loop_count)
- printk("qlogicisp: mbox_command loop timeout #1\n");
-
- switch(mbox_param[param[0]] >> 4) {
- case 8: isp_outw(param[7], host, MBOX7);
- case 7: isp_outw(param[6], host, MBOX6);
- case 6: isp_outw(param[5], host, MBOX5);
- case 5: isp_outw(param[4], host, MBOX4);
- case 4: isp_outw(param[3], host, MBOX3);
- case 3: isp_outw(param[2], host, MBOX2);
- case 2: isp_outw(param[1], host, MBOX1);
- case 1: isp_outw(param[0], host, MBOX0);
- }
-
- isp_outw(0x0, host, PCI_SEMAPHORE);
- isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
- isp_outw(HCCR_SET_HOST_INTR, host, HOST_HCCR);
-
- loop_count = DEFAULT_LOOP_COUNT;
- while (--loop_count && !(isp_inw(host, PCI_INTF_STS) & 0x04)) {
- barrier();
- cpu_relax();
- }
- if (!loop_count)
- printk("qlogicisp: mbox_command loop timeout #2\n");
-
- loop_count = DEFAULT_LOOP_COUNT;
- while (--loop_count && isp_inw(host, MBOX0) == 0x04) {
- barrier();
- cpu_relax();
- }
- if (!loop_count)
- printk("qlogicisp: mbox_command loop timeout #3\n");
-
- switch(mbox_param[param[0]] & 0xf) {
- case 8: param[7] = isp_inw(host, MBOX7);
- case 7: param[6] = isp_inw(host, MBOX6);
- case 6: param[5] = isp_inw(host, MBOX5);
- case 5: param[4] = isp_inw(host, MBOX4);
- case 4: param[3] = isp_inw(host, MBOX3);
- case 3: param[2] = isp_inw(host, MBOX2);
- case 2: param[1] = isp_inw(host, MBOX1);
- case 1: param[0] = isp_inw(host, MBOX0);
- }
-
- isp_outw(0x0, host, PCI_SEMAPHORE);
- isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
-
- return 0;
-}
-
-
-#if DEBUG_ISP1020_INTR
-
-void isp1020_print_status_entry(struct Status_Entry *status)
-{
- int i;
-
- printk("qlogicisp : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n",
- status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags);
- printk("qlogicisp : scsi status = 0x%04x, completion status = 0x%04x\n",
- le16_to_cpu(status->scsi_status), le16_to_cpu(status->completion_status));
- printk("qlogicisp : state flags = 0x%04x, status flags = 0x%04x\n",
- le16_to_cpu(status->state_flags), le16_to_cpu(status->status_flags));
- printk("qlogicisp : time = 0x%04x, request sense length = 0x%04x\n",
- le16_to_cpu(status->time), le16_to_cpu(status->req_sense_len));
- printk("qlogicisp : residual transfer length = 0x%08x\n",
- le32_to_cpu(status->residual));
-
- for (i = 0; i < le16_to_cpu(status->req_sense_len); i++)
- printk("qlogicisp : sense data = 0x%02x\n", status->req_sense_data[i]);
-}
-
-#endif /* DEBUG_ISP1020_INTR */
-
-
-#if DEBUG_ISP1020
-
-void isp1020_print_scsi_cmd(Scsi_Cmnd *cmd)
-{
- int i;
-
- printk("qlogicisp : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n",
- cmd->target, cmd->lun, cmd->cmd_len);
- printk("qlogicisp : command = ");
- for (i = 0; i < cmd->cmd_len; i++)
- printk("0x%02x ", cmd->cmnd[i]);
- printk("\n");
-}
-
-#endif /* DEBUG_ISP1020 */
-
-MODULE_LICENSE("GPL");
-
-static Scsi_Host_Template driver_template = {
- .detect = isp1020_detect,
- .release = isp1020_release,
- .info = isp1020_info,
- .queuecommand = isp1020_queuecommand,
- .bios_param = isp1020_biosparam,
- .can_queue = QLOGICISP_REQ_QUEUE_LEN,
- .this_id = -1,
- .sg_tablesize = QLOGICISP_MAX_SG(QLOGICISP_REQ_QUEUE_LEN),
- .cmd_per_lun = 1,
- .use_clustering = DISABLE_CLUSTERING,
-};
-#include "scsi_module.c"
diff --git a/drivers/scsi/qlogicisp_asm.c b/drivers/scsi/qlogicisp_asm.c
deleted file mode 100644
index 9ea4bec..0000000
--- a/drivers/scsi/qlogicisp_asm.c
+++ /dev/null
@@ -1,2034 +0,0 @@
-/*
- * Firmware Version 7.63.00 (12:07 Jan 27, 1999)
- */
-static const unsigned short risc_code_version = 7*1024+63;
-
-static const unsigned short risc_code_addr01 = 0x1000 ;
-
-#if RELOAD_FIRMWARE
-
-static const unsigned short risc_code01[] = {
- 0x0078, 0x103a, 0x0000, 0x3f14, 0x0000, 0x2043, 0x4f50, 0x5952,
- 0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
- 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
- 0x3130, 0x3230, 0x2049, 0x2f54, 0x2046, 0x6972, 0x6d77, 0x6172,
- 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, 0x372e, 0x3633,
- 0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20,
- 0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020,
- 0x3031, 0x2024, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x0048,
- 0x1045, 0x0038, 0x104b, 0x0078, 0x1047, 0x0028, 0x104b, 0x20b9,
- 0x1212, 0x0078, 0x104d, 0x20b9, 0x2222, 0x20c1, 0x0008, 0x2071,
- 0x0010, 0x70c3, 0x0004, 0x20c9, 0x76ff, 0x2089, 0x1186, 0x70c7,
- 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0007, 0x3f00,
- 0x70d6, 0x20c1, 0x0008, 0x2019, 0x0000, 0x2009, 0xfeff, 0x2100,
- 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64, 0x206b, 0x0a0a, 0xaddc,
- 0x3fff, 0x2b54, 0x205b, 0x5050, 0x2114, 0xa286, 0xa5a5, 0x0040,
- 0x10bf, 0xa386, 0x000f, 0x0040, 0x1085, 0x2c6a, 0x2a5a, 0x20c1,
- 0x0000, 0x2019, 0x000f, 0x0078, 0x1065, 0x2c6a, 0x2a5a, 0x20c1,
- 0x0008, 0x2009, 0x7fff, 0x2148, 0x2944, 0x204b, 0x0a0a, 0xa9bc,
- 0x3fff, 0x2734, 0x203b, 0x5050, 0x2114, 0xa286, 0x0a0a, 0x0040,
- 0x10a9, 0x284a, 0x263a, 0x20c1, 0x0004, 0x2009, 0x3fff, 0x2134,
- 0x200b, 0x5050, 0x2114, 0xa286, 0x5050, 0x0040, 0x10aa, 0x0078,
- 0x118e, 0x284a, 0x263a, 0x98c0, 0xa188, 0x1000, 0x212c, 0x200b,
- 0xa5a5, 0x2114, 0xa286, 0xa5a5, 0x0040, 0x10bc, 0x250a, 0xa18a,
- 0x1000, 0x98c1, 0x0078, 0x10c1, 0x250a, 0x0078, 0x10c1, 0x2c6a,
- 0x2a5a, 0x2130, 0xa18a, 0x0040, 0x2128, 0xa1a2, 0x5000, 0x8424,
- 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0xa192, 0x7700, 0x2009,
- 0x0000, 0x2001, 0x0031, 0x1078, 0x1c9d, 0x2218, 0x2079, 0x5000,
- 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109,
- 0x00c0, 0x10dc, 0x7ef2, 0x8528, 0x7de6, 0x7cea, 0x7bee, 0x7883,
- 0x0000, 0x2031, 0x0030, 0x78cf, 0x0101, 0x780b, 0x0002, 0x780f,
- 0x0002, 0x784f, 0x0003, 0x2069, 0x5040, 0x2001, 0x04fd, 0x2004,
- 0xa082, 0x0005, 0x0048, 0x1104, 0x0038, 0x1100, 0x0078, 0x1108,
- 0x681b, 0x003c, 0x0078, 0x110a, 0x00a8, 0x1108, 0x681b, 0x003c,
- 0x681b, 0x0028, 0x6807, 0x0007, 0x680b, 0x00fa, 0x680f, 0x0008,
- 0x6813, 0x0005, 0x6823, 0x0000, 0x6827, 0x0006, 0x6817, 0x0008,
- 0x682b, 0x0000, 0x681f, 0x0019, 0x2069, 0x5280, 0x2011, 0x0020,
- 0x2009, 0x0010, 0x680b, 0x080c, 0x680f, 0x0019, 0x6803, 0xfd00,
- 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004,
- 0x8109, 0x00c0, 0x1122, 0x2069, 0x5300, 0x2009, 0x0002, 0x20a9,
- 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bf0, 0xa386, 0xfeff,
- 0x00c0, 0x1148, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078, 0x114c,
- 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x0070, 0x1152,
- 0x0078, 0x1139, 0x8109, 0x00c0, 0x1137, 0x1078, 0x21e9, 0x1078,
- 0x46e9, 0x1078, 0x1946, 0x1078, 0x4bdf, 0x3200, 0xa085, 0x000d,
- 0x2090, 0x70c3, 0x0000, 0x0090, 0x116c, 0x70c0, 0xa086, 0x0002,
- 0x00c0, 0x116c, 0x1078, 0x1284, 0x1078, 0x1196, 0x78cc, 0xa005,
- 0x00c0, 0x117a, 0x1078, 0x1cc6, 0x0010, 0x1180, 0x0068, 0x1180,
- 0x1078, 0x20c8, 0x0010, 0x1180, 0x0068, 0x1180, 0x1078, 0x1a2b,
- 0x00e0, 0x116c, 0x1078, 0x4a66, 0x0078, 0x116c, 0x118e, 0x1190,
- 0x23ea, 0x23ea, 0x476a, 0x476a, 0x23ea, 0x23ea, 0x0078, 0x118e,
- 0x0078, 0x1190, 0x0078, 0x1192, 0x0078, 0x1194, 0x0068, 0x1201,
- 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1201, 0x7814,
- 0xa005, 0x00c0, 0x11a7, 0x0010, 0x1202, 0x0078, 0x1201, 0x2009,
- 0x505b, 0x2104, 0xa005, 0x00c0, 0x1201, 0x2009, 0x5064, 0x200b,
- 0x0000, 0x7914, 0xa186, 0x0042, 0x00c0, 0x11cc, 0x7816, 0x2009,
- 0x5062, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014, 0x70ca,
- 0x611c, 0xa18c, 0xff00, 0x6020, 0xa084, 0x00ff, 0xa105, 0x70ce,
- 0x1078, 0x192b, 0x0078, 0x11ff, 0x7814, 0xa086, 0x0018, 0x00c0,
- 0x11d3, 0x1078, 0x165a, 0x7817, 0x0000, 0x2009, 0x5062, 0x2104,
- 0xa065, 0x0040, 0x11ef, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1996,
- 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c, 0x6007,
- 0x0103, 0x1078, 0x1907, 0x00c0, 0x11fb, 0x1078, 0x192b, 0x2009,
- 0x5062, 0x200b, 0x0000, 0x2009, 0x505c, 0x2104, 0x200b, 0x0000,
- 0xa005, 0x0040, 0x11ff, 0x2001, 0x4005, 0x0078, 0x1286, 0x0078,
- 0x1284, 0x007c, 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000,
- 0x70cf, 0x0000, 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x1252, 0x2038,
- 0x0079, 0x1212, 0x1284, 0x12e5, 0x12a9, 0x12fe, 0x130d, 0x1313,
- 0x12a0, 0x1748, 0x1317, 0x1298, 0x12ad, 0x12af, 0x12b1, 0x12b3,
- 0x174d, 0x1298, 0x1329, 0x1360, 0x1672, 0x1742, 0x12b5, 0x1591,
- 0x15ad, 0x15c9, 0x15f4, 0x154a, 0x1558, 0x156c, 0x1580, 0x13df,
- 0x1298, 0x138d, 0x1393, 0x1398, 0x139d, 0x13a3, 0x13a8, 0x13ad,
- 0x13b2, 0x13b7, 0x13bb, 0x13d0, 0x13dc, 0x1298, 0x1298, 0x1298,
- 0x1298, 0x13eb, 0x13f4, 0x1403, 0x1429, 0x1433, 0x143a, 0x1480,
- 0x148f, 0x149e, 0x14b0, 0x152a, 0x153a, 0x1298, 0x1298, 0x1298,
- 0x1298, 0x153f, 0xa0bc, 0xffa0, 0x00c0, 0x1298, 0x2038, 0xa084,
- 0x001f, 0x0079, 0x125b, 0x1786, 0x1789, 0x1799, 0x1298, 0x1298,
- 0x18d8, 0x18f5, 0x1298, 0x1298, 0x1298, 0x18f9, 0x1901, 0x1298,
- 0x1298, 0x1298, 0x1298, 0x12db, 0x12f4, 0x131f, 0x1356, 0x1668,
- 0x1764, 0x1778, 0x1298, 0x1829, 0x1298, 0x18b4, 0x18be, 0x18c2,
- 0x18d0, 0x1298, 0x1298, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078,
- 0x1286, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068,
- 0x1287, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x00e0,
- 0x128f, 0x00e0, 0x1291, 0x0068, 0x1291, 0x2091, 0x4080, 0x007c,
- 0x70c3, 0x4001, 0x0078, 0x1287, 0x70c3, 0x4006, 0x0078, 0x1287,
- 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078,
- 0x1284, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x1284, 0x0078,
- 0x1284, 0x0078, 0x1284, 0x0078, 0x1284, 0x2091, 0x8000, 0x70c3,
- 0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
- 0x0007, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, 0x2031,
- 0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051, 0x0470, 0x2061,
- 0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091, 0x5000, 0x2091,
- 0x4080, 0x0078, 0x0455, 0x1078, 0x1b36, 0x00c0, 0x129c, 0x75d8,
- 0x74dc, 0x75da, 0x74de, 0x0078, 0x12e8, 0x2029, 0x0000, 0x2520,
- 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1a70, 0x0040, 0x1284,
- 0x70c3, 0x4002, 0x0078, 0x1284, 0x1078, 0x1b36, 0x00c0, 0x129c,
- 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1301, 0x2029, 0x0000,
- 0x2520, 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1ad0, 0x0040,
- 0x1284, 0x70c3, 0x4002, 0x0078, 0x1284, 0x71c4, 0x70c8, 0x2114,
- 0x200a, 0x0078, 0x1282, 0x71c4, 0x2114, 0x0078, 0x1282, 0x70c7,
- 0x0007, 0x70cb, 0x003f, 0x70cf, 0x0000, 0x0078, 0x1284, 0x1078,
- 0x1b36, 0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078,
- 0x132c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0,
- 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x1350, 0x8001,
- 0x7892, 0xa084, 0xfc00, 0x0040, 0x1345, 0x78cc, 0xa085, 0x0001,
- 0x78ce, 0x2001, 0x4005, 0x0078, 0x1286, 0x7a9a, 0x7b9e, 0x7da2,
- 0x7ea6, 0x7c96, 0x78cc, 0xa084, 0xfffc, 0x78ce, 0x0078, 0x1354,
- 0x78cc, 0xa085, 0x0001, 0x78ce, 0x0078, 0x1284, 0x1078, 0x1b36,
- 0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x1363,
- 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6,
- 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0040, 0x1387, 0x8001, 0x78ae,
- 0xa084, 0xfc00, 0x0040, 0x137c, 0x78cc, 0xa085, 0x0100, 0x78ce,
- 0x2001, 0x4005, 0x0078, 0x1286, 0x7ab6, 0x7bba, 0x7dbe, 0x7ec2,
- 0x7cb2, 0x78cc, 0xa084, 0xfcff, 0x78ce, 0x0078, 0x138b, 0x78cc,
- 0xa085, 0x0100, 0x78ce, 0x0078, 0x1284, 0x2009, 0x5061, 0x210c,
- 0x7aec, 0x0078, 0x1282, 0x2009, 0x5041, 0x210c, 0x0078, 0x1283,
- 0x2009, 0x5042, 0x210c, 0x0078, 0x1283, 0x2061, 0x5040, 0x610c,
- 0x6210, 0x0078, 0x1282, 0x2009, 0x5045, 0x210c, 0x0078, 0x1283,
- 0x2009, 0x5046, 0x210c, 0x0078, 0x1283, 0x2009, 0x5048, 0x210c,
- 0x0078, 0x1283, 0x2009, 0x5049, 0x210c, 0x0078, 0x1283, 0x7908,
- 0x7a0c, 0x0078, 0x1282, 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003,
- 0x8003, 0x8003, 0xa0e8, 0x5280, 0x6a00, 0x6804, 0xa084, 0x0008,
- 0x0040, 0x13cd, 0x6b08, 0x0078, 0x13ce, 0x6b0c, 0x0078, 0x1281,
- 0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091,
- 0x8001, 0x2708, 0x0078, 0x1281, 0x794c, 0x0078, 0x1283, 0x77c4,
- 0x1078, 0x1956, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x2091,
- 0x8001, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x127c,
- 0x1078, 0x22c1, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8,
- 0x127c, 0x2011, 0x5041, 0x2204, 0x007e, 0x2112, 0x1078, 0x227a,
- 0x017f, 0x0078, 0x1283, 0x71c4, 0x2011, 0x1421, 0x20a9, 0x0008,
- 0x2204, 0xa106, 0x0040, 0x1413, 0x8210, 0x0070, 0x1411, 0x0078,
- 0x1408, 0x0078, 0x127c, 0xa292, 0x1421, 0x027e, 0x2011, 0x5042,
- 0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x2286, 0x017f, 0x0078,
- 0x1283, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032,
- 0x004b, 0x2061, 0x5040, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8,
- 0x6012, 0x0078, 0x1282, 0x2061, 0x5040, 0x6114, 0x70c4, 0x6016,
- 0x0078, 0x1283, 0x2061, 0x5040, 0x71c4, 0x2011, 0x0004, 0x601f,
- 0x0019, 0x2019, 0x1212, 0xa186, 0x0028, 0x0040, 0x145b, 0x2011,
- 0x0005, 0x601f, 0x0019, 0x2019, 0x1212, 0xa186, 0x0032, 0x0040,
- 0x145b, 0x2011, 0x0006, 0x601f, 0x000c, 0x2019, 0x2222, 0xa186,
- 0x003c, 0x00c0, 0x127c, 0x6018, 0x007e, 0x611a, 0x7800, 0xa084,
- 0x0001, 0x00c0, 0x1476, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
- 0x0048, 0x146e, 0x0038, 0x1472, 0x0078, 0x1476, 0x0028, 0x1472,
- 0x0078, 0x1476, 0x2019, 0x2222, 0x0078, 0x1478, 0x2019, 0x1212,
- 0x23b8, 0x1078, 0x2297, 0x1078, 0x4bdf, 0x017f, 0x0078, 0x1283,
- 0x71c4, 0xa184, 0xffcf, 0x00c0, 0x127c, 0x2011, 0x5048, 0x2204,
- 0x2112, 0x007e, 0x1078, 0x22b9, 0x017f, 0x0078, 0x1283, 0x71c4,
- 0xa182, 0x0010, 0x00c8, 0x127c, 0x2011, 0x5049, 0x2204, 0x007e,
- 0x2112, 0x1078, 0x22a8, 0x017f, 0x0078, 0x1283, 0x71c4, 0x72c8,
- 0xa184, 0xfffd, 0x00c0, 0x127b, 0xa284, 0xfffd, 0x00c0, 0x127b,
- 0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e, 0x0078, 0x1282,
- 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
- 0x5280, 0x2019, 0x0000, 0x72c8, 0xa284, 0x0080, 0x0040, 0x14c6,
- 0x6c14, 0x84ff, 0x00c0, 0x14c6, 0x6817, 0x0040, 0xa284, 0x0040,
- 0x0040, 0x14d0, 0x6c10, 0x84ff, 0x00c0, 0x14d0, 0x6813, 0x0001,
- 0x6800, 0x007e, 0xa226, 0x0040, 0x14f3, 0x6a02, 0xa484, 0x2000,
- 0x0040, 0x14dc, 0xa39d, 0x0010, 0xa484, 0x1000, 0x0040, 0x14e2,
- 0xa39d, 0x0008, 0xa484, 0x4000, 0x0040, 0x14f3, 0x810f, 0xa284,
- 0x4000, 0x0040, 0x14ef, 0x1078, 0x22db, 0x0078, 0x14f3, 0x1078,
- 0x22cd, 0x0078, 0x14f3, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1522,
- 0xa2a4, 0x00ff, 0x2061, 0x5040, 0x6118, 0xa186, 0x0028, 0x0040,
- 0x1509, 0xa186, 0x0032, 0x0040, 0x150f, 0xa186, 0x003c, 0x0040,
- 0x1515, 0xa482, 0x0064, 0x0048, 0x151f, 0x0078, 0x1519, 0xa482,
- 0x0050, 0x0048, 0x151f, 0x0078, 0x1519, 0xa482, 0x0043, 0x0048,
- 0x151f, 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x127d, 0x6a0a,
- 0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4,
- 0x0078, 0x1281, 0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6a14,
- 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708,
- 0x0078, 0x1281, 0x70c4, 0x794c, 0x784e, 0x0078, 0x1283, 0x71c4,
- 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x127c, 0x1078, 0x22e9,
- 0x0078, 0x1281, 0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6a08,
- 0xa295, 0x0002, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282,
- 0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9,
- 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1567, 0x1078, 0x21b1, 0x2091,
- 0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x1078, 0x1956, 0x2091,
- 0x8000, 0x6a08, 0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005, 0x0040,
- 0x157b, 0x1078, 0x21b1, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282,
- 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091,
- 0x8000, 0x1078, 0x1963, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078,
- 0x1282, 0x77c4, 0x72c8, 0x73cc, 0x77c6, 0x72ca, 0x73ce, 0x1078,
- 0x19c4, 0x00c0, 0x15a9, 0x6818, 0xa005, 0x0040, 0x15a9, 0x2708,
- 0x1078, 0x22f9, 0x00c0, 0x15a9, 0x7817, 0x0015, 0x2091, 0x8001,
- 0x007c, 0x2091, 0x8001, 0x0078, 0x1284, 0x77c4, 0x77c6, 0x2041,
- 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
- 0x1963, 0x2061, 0x5040, 0x606f, 0x0003, 0x6782, 0x6093, 0x000f,
- 0x6073, 0x0000, 0x7817, 0x0016, 0x1078, 0x21b1, 0x2091, 0x8001,
- 0x007c, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091,
- 0x8000, 0x2061, 0x5040, 0x606f, 0x0002, 0x6073, 0x0000, 0x6782,
- 0x6093, 0x000f, 0x7817, 0x0017, 0x1078, 0x21b1, 0x2091, 0x8001,
- 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x2091, 0x8000,
- 0x1078, 0x1963, 0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0,
- 0x15e8, 0x2091, 0x8001, 0x007c, 0x78cc, 0xa084, 0x0003, 0x00c0,
- 0x1618, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051,
- 0x0008, 0x1078, 0x1956, 0x2091, 0x8000, 0x6808, 0xa80d, 0x690a,
- 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1601, 0xa7bc,
- 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1601,
- 0x2091, 0x8000, 0x2069, 0x0100, 0x6830, 0xa084, 0x0040, 0x0040,
- 0x1641, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004,
- 0x0040, 0x162e, 0x0070, 0x162e, 0x0078, 0x1625, 0x684b, 0x0009,
- 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040, 0x163b, 0x0070,
- 0x163b, 0x0078, 0x1632, 0x20a9, 0x00fa, 0x0070, 0x1641, 0x0078,
- 0x163d, 0x2079, 0x5000, 0x7817, 0x0018, 0x2061, 0x5040, 0x606f,
- 0x0001, 0x6073, 0x0000, 0x6093, 0x000f, 0x78cc, 0xa085, 0x0002,
- 0x78ce, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2091,
- 0x8001, 0x007c, 0x78cc, 0xa084, 0xfffd, 0x78ce, 0xa084, 0x0001,
- 0x00c0, 0x1664, 0x1078, 0x1a0e, 0x71c4, 0x71c6, 0x794a, 0x007c,
- 0x1078, 0x1b36, 0x00c0, 0x129c, 0x75d8, 0x74dc, 0x75da, 0x74de,
- 0x0078, 0x1675, 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc,
- 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x5000, 0x2091, 0x8000, 0x1078,
- 0x1911, 0x2091, 0x8001, 0x0040, 0x172c, 0x20a9, 0x0005, 0x20a1,
- 0x5018, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0020,
- 0x1078, 0x190c, 0x0040, 0x1698, 0x1078, 0x192b, 0x0078, 0x172c,
- 0x6004, 0xa084, 0xff00, 0x8007, 0x8009, 0x0040, 0x16fb, 0x0c7e,
- 0x2c68, 0x2091, 0x8000, 0x1078, 0x1911, 0x2091, 0x8001, 0x0040,
- 0x16cc, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x16a0, 0x609f, 0x0000,
- 0x0c7f, 0x0c7e, 0x7218, 0x731c, 0x7420, 0x7524, 0x2c68, 0x689c,
- 0xa065, 0x0040, 0x16fa, 0x2009, 0x0020, 0x1078, 0x190c, 0x00c0,
- 0x16e3, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0002, 0x00c0, 0x16cc,
- 0x2d00, 0x6002, 0x0078, 0x16b2, 0x0c7f, 0x0c7e, 0x609c, 0x2060,
- 0x1078, 0x1996, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009,
- 0x000c, 0x6008, 0xa085, 0x0200, 0x600a, 0x1078, 0x1907, 0x1078,
- 0x192b, 0x0078, 0x172c, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078,
- 0x1996, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c,
- 0x6007, 0x0103, 0x601b, 0x0003, 0x1078, 0x1907, 0x1078, 0x192b,
- 0x0078, 0x172c, 0x0c7f, 0x74c4, 0x73c8, 0x72cc, 0x6014, 0x2091,
- 0x8000, 0x7817, 0x0012, 0x0e7e, 0x2071, 0x5040, 0x706f, 0x0005,
- 0x7073, 0x0000, 0x7376, 0x727a, 0x747e, 0x7082, 0x7087, 0x0000,
- 0x2c00, 0x708a, 0x708f, 0x0000, 0xa02e, 0x2530, 0x611c, 0x61a2,
- 0xa184, 0x0060, 0x0040, 0x171e, 0x1078, 0x467f, 0x0e7f, 0x6596,
- 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x1078,
- 0x21b1, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287,
- 0x20a9, 0x0005, 0x2099, 0x5018, 0x2091, 0x8000, 0x530a, 0x2091,
- 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
- 0x0000, 0x007c, 0x71c4, 0x70c7, 0x0000, 0x7906, 0x0078, 0x1284,
- 0x71c4, 0x71c6, 0x2168, 0x0078, 0x174f, 0x2069, 0x1000, 0x690c,
- 0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1751, 0xa285,
- 0x0000, 0x00c0, 0x175f, 0x70c3, 0x4000, 0x0078, 0x1761, 0x70c3,
- 0x4003, 0x70ca, 0x0078, 0x1287, 0x2011, 0x5067, 0x220c, 0x70c4,
- 0x8003, 0x0048, 0x1771, 0x1078, 0x3b49, 0xa184, 0x7fff, 0x0078,
- 0x1775, 0x1078, 0x3b3c, 0xa185, 0x8000, 0x2012, 0x0078, 0x1283,
- 0x71c4, 0x1078, 0x3b33, 0x6100, 0x2001, 0x5067, 0x2004, 0xa084,
- 0x8000, 0xa10d, 0x6204, 0x6308, 0x0078, 0x1281, 0x79e4, 0x0078,
- 0x1283, 0x71c4, 0x71c6, 0x2198, 0x20a1, 0x0042, 0x20a9, 0x0004,
- 0x53a3, 0x21a0, 0x2099, 0x0042, 0x20a9, 0x0004, 0x53a3, 0x0078,
- 0x1284, 0x70c4, 0x2068, 0x2079, 0x5000, 0x2091, 0x8000, 0x1078,
- 0x1911, 0x2091, 0x8001, 0x0040, 0x1825, 0x6007, 0x0001, 0x600b,
- 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x6a10, 0xa28c, 0x000f,
- 0xa284, 0x00f0, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x6016,
- 0xa284, 0x0800, 0x0040, 0x17c0, 0x601b, 0x000a, 0x0078, 0x17c6,
- 0xa284, 0x1000, 0x0040, 0x17c6, 0x601b, 0x000c, 0xa284, 0x0300,
- 0x0040, 0x17cf, 0x602b, 0x0001, 0x8004, 0x8004, 0x8004, 0xa085,
- 0x0001, 0x601e, 0x6023, 0x0000, 0x6027, 0x0000, 0xa284, 0x0400,
- 0x0040, 0x17dc, 0x602b, 0x0000, 0x20a9, 0x0006, 0xac80, 0x000b,
- 0x20a0, 0xad80, 0x0005, 0x2098, 0x53a3, 0xa284, 0x0300, 0x00c0,
- 0x17f1, 0x6046, 0x604a, 0x604e, 0x6052, 0x6096, 0x609a, 0x0078,
- 0x17fb, 0x6800, 0x6046, 0x6804, 0x604a, 0x6e08, 0x664e, 0x6d0c,
- 0x6552, 0x6596, 0x669a, 0x6014, 0x2091, 0x8000, 0x7817, 0x0042,
- 0x2c08, 0x2061, 0x5040, 0x606f, 0x0005, 0x6073, 0x0000, 0x6077,
- 0x0000, 0x607b, 0x0000, 0x607f, 0x0000, 0x6082, 0x618a, 0xa284,
- 0x0400, 0x608e, 0x2091, 0x8001, 0x0e7e, 0x2071, 0x0020, 0x7007,
- 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x0e7f, 0x2091, 0x8000,
- 0x1078, 0x21b1, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078,
- 0x1287, 0x0c7e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2091, 0x8000, 0x2071,
- 0x5040, 0x2079, 0x0100, 0x2061, 0x0010, 0x70a0, 0xa06d, 0x0040,
- 0x18aa, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0007, 0x0040, 0x1844,
- 0xa286, 0x000f, 0x00c0, 0x18aa, 0x691c, 0xa184, 0x0080, 0x00c0,
- 0x18aa, 0x6824, 0xa18c, 0xff00, 0xa085, 0x0019, 0x6826, 0x71b0,
- 0x81ff, 0x0040, 0x1865, 0x0d7e, 0x2069, 0x0020, 0x6908, 0x6808,
- 0xa106, 0x00c0, 0x1856, 0x690c, 0x680c, 0xa106, 0x00c0, 0x185b,
- 0xa184, 0x00ff, 0x00c0, 0x185b, 0x0d7f, 0x78b8, 0xa084, 0x801f,
- 0x00c0, 0x1865, 0x7848, 0xa085, 0x000c, 0x784a, 0x71b0, 0x81ff,
- 0x0040, 0x1888, 0x70b3, 0x0000, 0x0d7e, 0x2069, 0x0020, 0x6807,
- 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0, 0x1879, 0x6807, 0x0008,
- 0x6804, 0xa084, 0x0008, 0x00c0, 0x1880, 0x6807, 0x0002, 0x0d7f,
- 0x61c4, 0x62c8, 0x63cc, 0x61c6, 0x62ca, 0x63ce, 0x0e7e, 0x2071,
- 0x5000, 0x7266, 0x736a, 0xae80, 0x0019, 0x0e7f, 0x1078, 0x4598,
- 0x78a3, 0x0000, 0x7858, 0xa084, 0xedff, 0x785a, 0x70b4, 0xa080,
- 0x00da, 0x781a, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001,
- 0x0078, 0x1284, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001,
- 0x2001, 0x4005, 0x0078, 0x1286, 0x7980, 0x71c6, 0x71c4, 0xa182,
- 0x0003, 0x00c8, 0x127c, 0x7982, 0x0078, 0x1284, 0x7980, 0x71c6,
- 0x0078, 0x1284, 0x7974, 0x71c6, 0x71c4, 0x7976, 0x7978, 0x71ca,
- 0x71c8, 0x797a, 0x797c, 0x71ce, 0x71cc, 0x797e, 0x0078, 0x1284,
- 0x7974, 0x71c6, 0x7978, 0x71ca, 0x797c, 0x71ce, 0x0078, 0x1284,
- 0x7900, 0x71c6, 0x71c4, 0x7902, 0x2001, 0x04fd, 0x2004, 0xa082,
- 0x0005, 0x0048, 0x18e7, 0x0038, 0x18e9, 0x0078, 0x18f3, 0x00a8,
- 0x18f3, 0xa18c, 0x0001, 0x00c0, 0x18f1, 0x20b9, 0x2222, 0x0078,
- 0x18f3, 0x20b9, 0x1212, 0x0078, 0x1284, 0x7900, 0x71c6, 0x0078,
- 0x1284, 0x2009, 0x5074, 0x2104, 0x70c6, 0x70c4, 0x200a, 0x0078,
- 0x1284, 0x2009, 0x5074, 0x2104, 0x70c6, 0x0078, 0x1284, 0xac80,
- 0x0001, 0x1078, 0x1af2, 0x007c, 0xac80, 0x0001, 0x1078, 0x1a92,
- 0x007c, 0x7850, 0xa065, 0x0040, 0x1919, 0x2c04, 0x7852, 0x2063,
- 0x0000, 0x007c, 0x0f7e, 0x2079, 0x5000, 0x7850, 0xa06d, 0x0040,
- 0x1929, 0x2d04, 0x7852, 0x6803, 0x0000, 0x6807, 0x0000, 0x680b,
- 0x0000, 0x0f7f, 0x007c, 0x2091, 0x8000, 0x0f7e, 0x2079, 0x5000,
- 0x7850, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1938, 0x1078, 0x23ca,
- 0x7852, 0x0f7f, 0x2091, 0x8001, 0x007c, 0x0f7e, 0x2079, 0x5000,
- 0x7850, 0x206a, 0x2d00, 0x7852, 0x0f7f, 0x007c, 0x2011, 0x7700,
- 0x7a52, 0x7bec, 0x8319, 0x0040, 0x1953, 0xa280, 0x0031, 0x2012,
- 0x2010, 0x0078, 0x194a, 0x2013, 0x0000, 0x007c, 0xa784, 0x0f00,
- 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105,
- 0xa0e8, 0x5300, 0x007c, 0x1078, 0x1956, 0x2900, 0x682a, 0x2a00,
- 0x682e, 0x6808, 0xa084, 0xffef, 0xa80d, 0x690a, 0x2009, 0x5052,
- 0x210c, 0x6804, 0xa005, 0x0040, 0x1995, 0xa116, 0x00c0, 0x1980,
- 0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x1983,
- 0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1992, 0x6000,
- 0x6806, 0x1078, 0x19a3, 0x1078, 0x1c42, 0x6810, 0x8001, 0x6812,
- 0x00c0, 0x1983, 0x017f, 0x6902, 0x6906, 0x007c, 0xa065, 0x0040,
- 0x19a2, 0x609c, 0x609f, 0x0000, 0x2008, 0x1078, 0x192b, 0x2100,
- 0x0078, 0x1996, 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9,
- 0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828,
- 0x601a, 0x682c, 0x6022, 0x007c, 0x0e7e, 0x2071, 0x5040, 0x704c,
- 0xa08c, 0x0200, 0x00c0, 0x19c2, 0xa088, 0x5080, 0x2d0a, 0x8000,
- 0x704e, 0xa006, 0x0e7f, 0x007c, 0x1078, 0x1956, 0x2091, 0x8000,
- 0x6804, 0x781e, 0xa065, 0x0040, 0x1a0d, 0x0078, 0x19d5, 0x2c00,
- 0x781e, 0x6000, 0xa065, 0x0040, 0x1a0d, 0x600c, 0xa306, 0x00c0,
- 0x19cf, 0x6010, 0xa206, 0x00c0, 0x19cf, 0x2c28, 0x2001, 0x5052,
- 0x2004, 0xac06, 0x00c0, 0x19e6, 0x0078, 0x1a0b, 0x6804, 0xac06,
- 0x00c0, 0x19f3, 0x6000, 0xa065, 0x6806, 0x00c0, 0x19fd, 0x6803,
- 0x0000, 0x0078, 0x19fd, 0x6400, 0x781c, 0x2060, 0x6402, 0xa486,
- 0x0000, 0x00c0, 0x19fd, 0x2c00, 0x6802, 0x2560, 0x1078, 0x19a3,
- 0x601b, 0x0005, 0x6023, 0x0020, 0x1078, 0x1c42, 0x6810, 0x8001,
- 0x1050, 0x23ca, 0x6812, 0xa085, 0xffff, 0x007c, 0x2039, 0x0000,
- 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000,
- 0x1078, 0x1963, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1a18, 0xa7bc,
- 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1a18,
- 0x2091, 0x8001, 0x007c, 0x2061, 0x0000, 0x6018, 0xa084, 0x0001,
- 0x00c0, 0x1a3c, 0x2091, 0x8000, 0x78e0, 0x78e3, 0x0000, 0x2091,
- 0x8001, 0xa005, 0x00c0, 0x1a3d, 0x007c, 0xa08c, 0xfff0, 0x0040,
- 0x1a43, 0x1078, 0x23ca, 0x0079, 0x1a45, 0x1a55, 0x1a58, 0x1a5e,
- 0x1a62, 0x1a56, 0x1a66, 0x1a6c, 0x1a56, 0x1a56, 0x1c0c, 0x1c30,
- 0x1c34, 0x1a56, 0x1a56, 0x1a56, 0x1a56, 0x007c, 0x1078, 0x23ca,
- 0x1078, 0x1a0e, 0x2001, 0x8001, 0x0078, 0x1c3a, 0x2001, 0x8003,
- 0x0078, 0x1c3a, 0x2001, 0x8004, 0x0078, 0x1c3a, 0x1078, 0x1a0e,
- 0x2001, 0x8006, 0x0078, 0x1c3a, 0x2001, 0x8007, 0x0078, 0x1c3a,
- 0x2030, 0x2138, 0xa782, 0x0021, 0x0048, 0x1a78, 0x2009, 0x0020,
- 0x2600, 0x1078, 0x1a92, 0x00c0, 0x1a91, 0xa7ba, 0x0020, 0x0048,
- 0x1a90, 0x0040, 0x1a90, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040,
- 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1a72,
- 0xa006, 0x007c, 0x81ff, 0x0040, 0x1acd, 0x2099, 0x0030, 0x20a0,
- 0x700c, 0xa084, 0x00ff, 0x0040, 0x1aa4, 0x7007, 0x0004, 0x7004,
- 0xa084, 0x0004, 0x00c0, 0x1a9f, 0x21a8, 0x7017, 0x0000, 0x810b,
- 0x7112, 0x721a, 0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0001,
- 0x7002, 0x7007, 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
- 0x00c8, 0x1ac1, 0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0,
- 0x1ab3, 0x7008, 0x800b, 0x00c8, 0x1ab3, 0x7007, 0x0002, 0xa08c,
- 0x01e0, 0x00c0, 0x1acd, 0x53a5, 0xa006, 0x7003, 0x0000, 0x007c,
- 0x2030, 0x2138, 0xa782, 0x0021, 0x0048, 0x1ad8, 0x2009, 0x0020,
- 0x2600, 0x1078, 0x1af2, 0x00c0, 0x1af1, 0xa7ba, 0x0020, 0x0048,
- 0x1af0, 0x0040, 0x1af0, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040,
- 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1ad2,
- 0xa006, 0x007c, 0x81ff, 0x0040, 0x1b33, 0x2098, 0x20a1, 0x0030,
- 0x700c, 0xa084, 0x00ff, 0x0040, 0x1b04, 0x7007, 0x0004, 0x7004,
- 0xa084, 0x0004, 0x00c0, 0x1aff, 0x21a8, 0x7017, 0x0000, 0x810b,
- 0x7112, 0x721a, 0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0000,
- 0x7002, 0x53a6, 0x7007, 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082,
- 0x0005, 0x00c8, 0x1b22, 0x2009, 0x0022, 0x2104, 0xa084, 0x4000,
- 0x00c0, 0x1b14, 0x7010, 0xa084, 0xf000, 0x0040, 0x1b2b, 0x7007,
- 0x0008, 0x0078, 0x1b2f, 0x7108, 0x8103, 0x00c8, 0x1b14, 0x7007,
- 0x0002, 0xa184, 0x01e0, 0x7003, 0x0000, 0x007c, 0x2001, 0x04fd,
- 0x2004, 0xa082, 0x0004, 0x00c8, 0x1b3f, 0x0078, 0x1b42, 0xa006,
- 0x0078, 0x1b44, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x2071, 0x5000,
- 0x2d08, 0x7058, 0x6802, 0xa005, 0x00c0, 0x1b4f, 0x715e, 0x715a,
- 0x0e7f, 0x007c, 0x2c08, 0x7858, 0x6002, 0xa005, 0x00c0, 0x1b59,
- 0x795e, 0x795a, 0x007c, 0x2091, 0x8000, 0x6003, 0x0000, 0x2c08,
- 0x785c, 0xa065, 0x00c0, 0x1b67, 0x795a, 0x0078, 0x1b68, 0x6102,
- 0x795e, 0x2091, 0x8001, 0x1078, 0x21ce, 0x007c, 0x0e7e, 0x2071,
- 0x5000, 0x7058, 0xa06d, 0x0040, 0x1b7c, 0x6800, 0x705a, 0xa005,
- 0x00c0, 0x1b7b, 0x705e, 0x8dff, 0x0e7f, 0x007c, 0x0d7e, 0x0c7e,
- 0x0f7e, 0x2079, 0x5000, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa005,
- 0x0040, 0x1bac, 0x2068, 0x6814, 0xa306, 0x00c0, 0x1b95, 0x6828,
- 0xa084, 0x00ff, 0xa406, 0x0040, 0x1b98, 0x2d60, 0x0078, 0x1b86,
- 0x6800, 0xa005, 0x6002, 0x00c0, 0x1ba4, 0xaf80, 0x0016, 0xac06,
- 0x0040, 0x1ba3, 0x2c00, 0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040,
- 0x1bab, 0x1078, 0x1996, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005,
- 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5000, 0xaf80, 0x0016,
- 0x2060, 0x6000, 0xa005, 0x0040, 0x1bdb, 0x2068, 0x6814, 0xa084,
- 0x00ff, 0xa306, 0x0040, 0x1bc7, 0x2d60, 0x0078, 0x1bb9, 0x6800,
- 0xa005, 0x6002, 0x00c0, 0x1bd3, 0xaf80, 0x0016, 0xac06, 0x0040,
- 0x1bd2, 0x2c00, 0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040, 0x1bda,
- 0x1078, 0x1996, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c,
- 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5000, 0xaf80, 0x0016, 0x2060,
- 0x6000, 0xa06d, 0x0040, 0x1c07, 0x6814, 0xa306, 0x0040, 0x1bf3,
- 0x2d60, 0x0078, 0x1be8, 0x6800, 0xa005, 0x6002, 0x00c0, 0x1bff,
- 0xaf80, 0x0016, 0xac06, 0x0040, 0x1bfe, 0x2c00, 0x785e, 0x0d7e,
- 0x689c, 0xa005, 0x0040, 0x1c06, 0x1078, 0x1996, 0x007f, 0x0f7f,
- 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x2091, 0x8000, 0x2069, 0x5040,
- 0x6800, 0xa086, 0x0000, 0x0040, 0x1c1a, 0x2091, 0x8001, 0x78e3,
- 0x0009, 0x007c, 0x6880, 0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049,
- 0x0004, 0x2051, 0x0010, 0x1078, 0x1963, 0x8738, 0xa784, 0x001f,
- 0x00c0, 0x1c23, 0x2091, 0x8001, 0x2001, 0x800a, 0x0078, 0x1c3a,
- 0x2001, 0x800c, 0x0078, 0x1c3a, 0x1078, 0x1a0e, 0x2001, 0x800d,
- 0x0078, 0x1c3a, 0x70c2, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091,
- 0x4080, 0x007c, 0x6004, 0x2c08, 0x2063, 0x0000, 0x7884, 0x8000,
- 0x7886, 0x7888, 0xa005, 0x798a, 0x0040, 0x1c51, 0x2c02, 0x0078,
- 0x1c52, 0x798e, 0x007c, 0x6807, 0x0103, 0x0c7e, 0x2061, 0x5000,
- 0x2d08, 0x206b, 0x0000, 0x6084, 0x8000, 0x6086, 0x6088, 0xa005,
- 0x618a, 0x0040, 0x1c66, 0x2d02, 0x0078, 0x1c67, 0x618e, 0x0c7f,
- 0x007c, 0x1078, 0x1c7a, 0x0040, 0x1c79, 0x0c7e, 0x609c, 0xa065,
- 0x0040, 0x1c74, 0x1078, 0x1996, 0x0c7f, 0x609f, 0x0000, 0x1078,
- 0x192b, 0x007c, 0x788c, 0xa065, 0x0040, 0x1c8c, 0x2091, 0x8000,
- 0x7884, 0x8001, 0x7886, 0x2c04, 0x788e, 0xa005, 0x00c0, 0x1c8a,
- 0x788a, 0x8000, 0x2091, 0x8001, 0x007c, 0x20a9, 0x0010, 0xa006,
- 0x8004, 0x8086, 0x818e, 0x00c8, 0x1c96, 0xa200, 0x0070, 0x1c9a,
- 0x0078, 0x1c91, 0x8086, 0x818e, 0x007c, 0x157e, 0x20a9, 0x0010,
- 0xa005, 0x0040, 0x1cc0, 0xa11a, 0x00c8, 0x1cc0, 0x8213, 0x818d,
- 0x0048, 0x1cb1, 0xa11a, 0x00c8, 0x1cb2, 0x0070, 0x1cb8, 0x0078,
- 0x1ca6, 0xa11a, 0x2308, 0x8210, 0x0070, 0x1cb8, 0x0078, 0x1ca6,
- 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c,
- 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x1cbc, 0x7994, 0x70d0,
- 0xa106, 0x0040, 0x1d34, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004,
- 0xa005, 0x00c0, 0x1d34, 0x7008, 0x7208, 0xa206, 0x00c0, 0x1d34,
- 0xa286, 0x0008, 0x00c0, 0x1d34, 0x2071, 0x0010, 0x1078, 0x1911,
- 0x0040, 0x1d34, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa184, 0xff00,
- 0x0040, 0x1d02, 0x2031, 0x0000, 0x810b, 0x86b5, 0x810b, 0x86b5,
- 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5,
- 0x2100, 0xa210, 0x2600, 0xa319, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
- 0x0078, 0x1d0c, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399, 0x0000,
- 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x2009, 0x0020, 0x1078, 0x190c,
- 0x2091, 0x8001, 0x0040, 0x1d2b, 0x1078, 0x192b, 0x78a8, 0x8000,
- 0x78aa, 0xa086, 0x0002, 0x00c0, 0x1d34, 0x2091, 0x8000, 0x78e3,
- 0x0002, 0x78ab, 0x0000, 0x78cc, 0xa085, 0x0003, 0x78ce, 0x2091,
- 0x8001, 0x0078, 0x1d34, 0x78ab, 0x0000, 0x1078, 0x208b, 0x6004,
- 0xa084, 0x000f, 0x0079, 0x1d39, 0x2071, 0x0010, 0x2091, 0x8001,
- 0x007c, 0x1d49, 0x1d6b, 0x1d91, 0x1d49, 0x1dae, 0x1d58, 0x1f0d,
- 0x1f28, 0x1d49, 0x1d65, 0x1d8b, 0x1df6, 0x1e63, 0x1eb3, 0x1ec5,
- 0x1f24, 0x2039, 0x0400, 0x78dc, 0xa705, 0x78de, 0x6008, 0xa705,
- 0x600a, 0x1078, 0x1fa6, 0x609c, 0x78da, 0x1078, 0x2073, 0x007c,
- 0x78dc, 0xa084, 0x0100, 0x0040, 0x1d5f, 0x0078, 0x1d49, 0x601c,
- 0xa085, 0x0080, 0x601e, 0x0078, 0x1d72, 0x1078, 0x1b36, 0x00c0,
- 0x1d49, 0x1078, 0x20a5, 0x78dc, 0xa084, 0x0100, 0x0040, 0x1d72,
- 0x0078, 0x1d49, 0x78df, 0x0000, 0x6004, 0x8007, 0xa084, 0x00ff,
- 0x78d2, 0x8001, 0x609f, 0x0000, 0x0040, 0x1d88, 0x1078, 0x1fa6,
- 0x0040, 0x1d88, 0x78dc, 0xa085, 0x0100, 0x78de, 0x0078, 0x1d8a,
- 0x1078, 0x1fca, 0x007c, 0x1078, 0x1b36, 0x00c0, 0x1d49, 0x1078,
- 0x20a1, 0x78dc, 0xa08c, 0x0e00, 0x00c0, 0x1d9a, 0xa084, 0x0100,
- 0x00c0, 0x1d9c, 0x0078, 0x1d49, 0x1078, 0x1fa6, 0x00c0, 0x1dad,
- 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x1f63, 0xa186,
- 0x000f, 0x0040, 0x1f63, 0x1078, 0x1fca, 0x007c, 0x78dc, 0xa084,
- 0x0100, 0x0040, 0x1db5, 0x0078, 0x1d49, 0x78df, 0x0000, 0x6714,
- 0x2011, 0x0001, 0x20a9, 0x0001, 0x6018, 0xa084, 0x00ff, 0xa005,
- 0x0040, 0x1dd8, 0x2011, 0x0001, 0xa7bc, 0xff00, 0x20a9, 0x0020,
- 0xa08e, 0x0001, 0x0040, 0x1dd8, 0x2039, 0x0000, 0x2011, 0x0002,
- 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040, 0x1dd8, 0x0078, 0x1df3,
- 0x1078, 0x1956, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000,
- 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001,
- 0x0070, 0x1dec, 0x0078, 0x1dda, 0x8211, 0x0040, 0x1df3, 0x20a9,
- 0x0100, 0x0078, 0x1dda, 0x1078, 0x192b, 0x007c, 0x2001, 0x5067,
- 0x2004, 0xa084, 0x8000, 0x0040, 0x1f8b, 0x6114, 0x1078, 0x20c2,
- 0x6900, 0xa184, 0x0001, 0x0040, 0x1e17, 0x6028, 0xa084, 0x00ff,
- 0x00c0, 0x1f83, 0x6800, 0xa084, 0x0001, 0x0040, 0x1f8b, 0x6803,
- 0x0000, 0x680b, 0x0000, 0x6807, 0x0000, 0x0078, 0x1f93, 0x2011,
- 0x0001, 0x6020, 0xa084, 0x4000, 0x0040, 0x1e20, 0xa295, 0x0002,
- 0x6020, 0xa084, 0x0100, 0x0040, 0x1e27, 0xa295, 0x0008, 0x601c,
- 0xa084, 0x0002, 0x0040, 0x1e2e, 0xa295, 0x0004, 0x602c, 0xa08c,
- 0x00ff, 0xa182, 0x0002, 0x0048, 0x1f8f, 0xa182, 0x001b, 0x00c8,
- 0x1f8f, 0x0040, 0x1f8f, 0x690e, 0x602c, 0x8007, 0xa08c, 0x00ff,
- 0xa182, 0x0002, 0x0048, 0x1f8f, 0xa182, 0x001b, 0x00c8, 0x1f8f,
- 0x0040, 0x1f8f, 0x6912, 0x6030, 0xa005, 0x00c0, 0x1e51, 0x2001,
- 0x001e, 0x8000, 0x6816, 0x6028, 0xa084, 0x00ff, 0x0040, 0x1f8b,
- 0x6806, 0x6028, 0x8007, 0xa084, 0x00ff, 0x0040, 0x1f8b, 0x680a,
- 0x6a02, 0x0078, 0x1f93, 0x2001, 0x5067, 0x2004, 0xa084, 0x8000,
- 0x0040, 0x1f8b, 0x6114, 0x1078, 0x20c2, 0x2091, 0x8000, 0x6a04,
- 0x6b08, 0x6418, 0xa484, 0x0003, 0x0040, 0x1e89, 0x6128, 0xa18c,
- 0x00ff, 0x8001, 0x00c0, 0x1e82, 0x2100, 0xa210, 0x0048, 0x1eaf,
- 0x0078, 0x1e89, 0x8001, 0x00c0, 0x1eaf, 0x2100, 0xa212, 0x0048,
- 0x1eaf, 0xa484, 0x000c, 0x0040, 0x1ea3, 0x6128, 0x810f, 0xa18c,
- 0x00ff, 0xa082, 0x0004, 0x00c0, 0x1e9b, 0x2100, 0xa318, 0x0048,
- 0x1eaf, 0x0078, 0x1ea3, 0xa082, 0x0004, 0x00c0, 0x1eaf, 0x2100,
- 0xa31a, 0x0048, 0x1eaf, 0x6030, 0xa005, 0x0040, 0x1ea9, 0x8000,
- 0x6816, 0x6a06, 0x6b0a, 0x2091, 0x8001, 0x0078, 0x1f93, 0x2091,
- 0x8001, 0x0078, 0x1f8f, 0x6114, 0x1078, 0x20c2, 0x2091, 0x8000,
- 0x6b08, 0x8318, 0x0048, 0x1ec1, 0x6b0a, 0x2091, 0x8001, 0x0078,
- 0x1fa2, 0x2091, 0x8001, 0x0078, 0x1f8f, 0x6024, 0x8007, 0xa084,
- 0x00ff, 0x0040, 0x1ee3, 0xa086, 0x0080, 0x00c0, 0x1f0b, 0x20a9,
- 0x0008, 0x2069, 0x7410, 0x2091, 0x8000, 0x6800, 0xa084, 0xfcff,
- 0x6802, 0xade8, 0x0008, 0x0070, 0x1edf, 0x0078, 0x1ed5, 0x2091,
- 0x8001, 0x0078, 0x1f93, 0x6028, 0xa015, 0x0040, 0x1f0b, 0x6114,
- 0x1078, 0x20c2, 0x0d7e, 0xade8, 0x0007, 0x2091, 0x8000, 0x6800,
- 0xa00d, 0x0040, 0x1f08, 0xa206, 0x0040, 0x1ef9, 0x2168, 0x0078,
- 0x1eef, 0x0c7e, 0x2160, 0x6000, 0x6802, 0x1078, 0x192b, 0x0c7f,
- 0x0d7f, 0x6808, 0x8000, 0x680a, 0x2091, 0x8001, 0x0078, 0x1fa2,
- 0x2091, 0x8001, 0x0d7f, 0x0078, 0x1f8b, 0x6114, 0x1078, 0x20c2,
- 0x6800, 0xa084, 0x0001, 0x0040, 0x1f7b, 0x2091, 0x8000, 0x6a04,
- 0x8210, 0x0048, 0x1f20, 0x6a06, 0x2091, 0x8001, 0x0078, 0x1fa2,
- 0x2091, 0x8001, 0x0078, 0x1f8f, 0x1078, 0x1b36, 0x00c0, 0x1d49,
- 0x6114, 0x1078, 0x20c2, 0x60be, 0x6900, 0xa184, 0x0008, 0x0040,
- 0x1f35, 0x6020, 0xa085, 0x0100, 0x6022, 0xa184, 0x0001, 0x0040,
- 0x1f8b, 0xa184, 0x0100, 0x00c0, 0x1f77, 0xa184, 0x0200, 0x00c0,
- 0x1f73, 0x681c, 0xa005, 0x00c0, 0x1f7f, 0x6004, 0xa084, 0x00ff,
- 0xa086, 0x000f, 0x00c0, 0x1f4e, 0x1078, 0x20a5, 0x78df, 0x0000,
- 0x6004, 0x8007, 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f, 0x0000,
- 0x0040, 0x1f63, 0x1078, 0x1fa6, 0x0040, 0x1f63, 0x78dc, 0xa085,
- 0x0100, 0x78de, 0x007c, 0x78d7, 0x0000, 0x78db, 0x0000, 0x6024,
- 0xa084, 0xff00, 0x6026, 0x1078, 0x39aa, 0x0040, 0x1cc6, 0x1078,
- 0x1b5b, 0x0078, 0x1cc6, 0x2009, 0x0017, 0x0078, 0x1f95, 0x2009,
- 0x000e, 0x0078, 0x1f95, 0x2009, 0x0007, 0x0078, 0x1f95, 0x2009,
- 0x0035, 0x0078, 0x1f95, 0x2009, 0x003e, 0x0078, 0x1f95, 0x2009,
- 0x0004, 0x0078, 0x1f95, 0x2009, 0x0006, 0x0078, 0x1f95, 0x2009,
- 0x0016, 0x0078, 0x1f95, 0x2009, 0x0001, 0x6024, 0xa084, 0xff00,
- 0xa105, 0x6026, 0x2091, 0x8000, 0x1078, 0x1c42, 0x2091, 0x8001,
- 0x0078, 0x1cc6, 0x1078, 0x192b, 0x0078, 0x1cc6, 0x78d4, 0xa06d,
- 0x00c0, 0x1fb1, 0x2c00, 0x78d6, 0x78da, 0x609f, 0x0000, 0x0078,
- 0x1fbd, 0x2c00, 0x689e, 0x609f, 0x0000, 0x78d6, 0x2d00, 0x6002,
- 0x78d8, 0xad06, 0x00c0, 0x1fbd, 0x6002, 0x78d0, 0x8001, 0x78d2,
- 0x00c0, 0x1fc9, 0x78dc, 0xa084, 0xfeff, 0x78de, 0x78d8, 0x2060,
- 0xa006, 0x007c, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0xe1ff,
- 0x601e, 0xa184, 0x0060, 0x0040, 0x1fd9, 0x0e7e, 0x1078, 0x467f,
- 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3,
- 0x0000, 0x6714, 0x1078, 0x1956, 0x2091, 0x8000, 0x60a0, 0xa084,
- 0x8000, 0x00c0, 0x2000, 0x6808, 0xa084, 0x0001, 0x0040, 0x2000,
- 0x2091, 0x8001, 0x1078, 0x19a3, 0x2091, 0x8000, 0x1078, 0x1c42,
- 0x2091, 0x8001, 0x78d7, 0x0000, 0x78db, 0x0000, 0x0078, 0x2072,
- 0x6024, 0xa096, 0x0001, 0x00c0, 0x2007, 0x8000, 0x6026, 0x6a10,
- 0x6814, 0x2091, 0x8001, 0xa202, 0x0048, 0x2016, 0x0040, 0x2016,
- 0x2039, 0x0200, 0x1078, 0x2073, 0x0078, 0x2072, 0x2c08, 0x2091,
- 0x8000, 0x60a0, 0xa084, 0x8000, 0x0040, 0x2043, 0x6800, 0xa065,
- 0x0040, 0x2048, 0x6a04, 0x0e7e, 0x2071, 0x5040, 0x7000, 0xa084,
- 0x0001, 0x0040, 0x203d, 0x7048, 0xa206, 0x00c0, 0x203d, 0x6b04,
- 0x231c, 0x2160, 0x6302, 0x2300, 0xa005, 0x00c0, 0x2038, 0x6902,
- 0x2260, 0x6102, 0x0e7f, 0x0078, 0x204f, 0x2160, 0x6202, 0x6906,
- 0x0e7f, 0x0078, 0x204f, 0x6800, 0xa065, 0x0040, 0x2048, 0x6102,
- 0x6902, 0x00c0, 0x204c, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160,
- 0x60a0, 0xa084, 0x8000, 0x0040, 0x2059, 0x6808, 0xa084, 0xfffc,
- 0x680a, 0x6810, 0x8000, 0x6812, 0x2091, 0x8001, 0x6808, 0xa08c,
- 0x0040, 0x0040, 0x2068, 0xa086, 0x0040, 0x680a, 0x1078, 0x19b4,
- 0x2091, 0x8000, 0x1078, 0x21b1, 0x2091, 0x8001, 0x78db, 0x0000,
- 0x78d7, 0x0000, 0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000,
- 0x1078, 0x1c42, 0x2091, 0x8001, 0x78d8, 0xa065, 0x0040, 0x2086,
- 0x609c, 0x78da, 0x609f, 0x0000, 0x0078, 0x2076, 0x78d7, 0x0000,
- 0x78db, 0x0000, 0x007c, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8,
- 0x2092, 0xa006, 0x7896, 0x70d2, 0x7804, 0xa005, 0x0040, 0x20a0,
- 0x8001, 0x7806, 0x00c0, 0x20a0, 0x0068, 0x20a0, 0x2091, 0x4080,
- 0x007c, 0x2039, 0x20b9, 0x0078, 0x20a7, 0x2039, 0x20bf, 0x2704,
- 0xa005, 0x0040, 0x20b8, 0xac00, 0x2068, 0x6b08, 0x6c0c, 0x6910,
- 0x6a14, 0x690a, 0x6a0e, 0x6b12, 0x6c16, 0x8738, 0x0078, 0x20a7,
- 0x007c, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015,
- 0x001b, 0x0000, 0x0c7e, 0x1078, 0x3b33, 0x2c68, 0x0c7f, 0x007c,
- 0x0010, 0x2139, 0x0068, 0x2139, 0x2029, 0x0000, 0x78cb, 0x0000,
- 0x788c, 0xa065, 0x0040, 0x2132, 0x2009, 0x5074, 0x2104, 0xa084,
- 0x0001, 0x0040, 0x2100, 0x6004, 0xa086, 0x0103, 0x00c0, 0x2100,
- 0x6018, 0xa005, 0x00c0, 0x2100, 0x6014, 0xa005, 0x00c0, 0x2100,
- 0x0d7e, 0x2069, 0x0000, 0x6818, 0xa084, 0x0001, 0x00c0, 0x20ff,
- 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001,
- 0x2091, 0x4080, 0x0d7f, 0x1078, 0x1c69, 0x0078, 0x2137, 0x0d7f,
- 0x1078, 0x213a, 0x0040, 0x2132, 0x6204, 0xa294, 0x00ff, 0xa296,
- 0x0003, 0x0040, 0x2112, 0x6204, 0xa296, 0x0110, 0x00c0, 0x2120,
- 0x78cb, 0x0001, 0x6204, 0xa294, 0xff00, 0x8217, 0x8211, 0x0040,
- 0x2120, 0x85ff, 0x00c0, 0x2132, 0x8210, 0xa202, 0x00c8, 0x2132,
- 0x057e, 0x1078, 0x2149, 0x057f, 0x0040, 0x212d, 0x78e0, 0xa086,
- 0x0003, 0x0040, 0x2132, 0x0078, 0x2120, 0x8528, 0x78c8, 0xa005,
- 0x0040, 0x20d0, 0x85ff, 0x0040, 0x2139, 0x2091, 0x4080, 0x78b0,
- 0x70d6, 0x007c, 0x7bac, 0x79b0, 0x70d4, 0xa102, 0x00c0, 0x2143,
- 0x2300, 0xa005, 0x007c, 0x0048, 0x2147, 0xa302, 0x007c, 0x8002,
- 0x007c, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x2163,
- 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2198,
- 0x7008, 0x7208, 0xa206, 0x00c0, 0x2198, 0xa286, 0x0008, 0x00c0,
- 0x2198, 0x2071, 0x0010, 0x1078, 0x219d, 0x2009, 0x0020, 0x6004,
- 0xa086, 0x0103, 0x00c0, 0x2172, 0x6028, 0xa005, 0x00c0, 0x2172,
- 0x2009, 0x000c, 0x1078, 0x1907, 0x0040, 0x218b, 0x78c4, 0x8000,
- 0x78c6, 0xa086, 0x0002, 0x00c0, 0x2198, 0x2091, 0x8000, 0x78e3,
- 0x0003, 0x78c7, 0x0000, 0x78cc, 0xa085, 0x0300, 0x78ce, 0x2091,
- 0x8001, 0x0078, 0x2198, 0x78c7, 0x0000, 0x1078, 0x1c69, 0x79ac,
- 0x78b0, 0x8000, 0xa10a, 0x00c8, 0x2196, 0xa006, 0x78b2, 0xa006,
- 0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x8107, 0x8004, 0x8004,
- 0x7ab8, 0x7bb4, 0x7cc0, 0x7dbc, 0xa210, 0xa399, 0x0000, 0xa4a1,
- 0x0000, 0xa5a9, 0x0000, 0x007c, 0x2009, 0x505b, 0x2091, 0x8000,
- 0x200a, 0x0f7e, 0x0e7e, 0x2071, 0x5040, 0x7000, 0xa086, 0x0000,
- 0x00c0, 0x21cb, 0x2009, 0x5012, 0x2104, 0xa005, 0x00c0, 0x21cb,
- 0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x21cb, 0x0018,
- 0x21cb, 0x781b, 0x004b, 0x0e7f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e,
- 0x2071, 0x5040, 0x2091, 0x8000, 0x7000, 0xa086, 0x0000, 0x00c0,
- 0x21e4, 0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x21e4,
- 0x0018, 0x21e4, 0x781b, 0x004d, 0x2091, 0x8001, 0x0e7f, 0x0f7f,
- 0x007c, 0x127e, 0x2091, 0x2300, 0x2071, 0x5040, 0x2079, 0x0100,
- 0x784b, 0x000f, 0x0098, 0x21f7, 0x7838, 0x0078, 0x21f0, 0x20a9,
- 0x0040, 0x7800, 0xa082, 0x0004, 0x0048, 0x2200, 0x20a9, 0x0060,
- 0x789b, 0x0000, 0x78af, 0x0000, 0x78af, 0x0000, 0x0070, 0x220a,
- 0x0078, 0x2202, 0x7800, 0xa082, 0x0004, 0x0048, 0x2219, 0x70b7,
- 0x009b, 0x2019, 0x4da4, 0x1078, 0x2255, 0x702f, 0x8001, 0x0078,
- 0x2225, 0x70b7, 0x0000, 0x2019, 0x4c1c, 0x1078, 0x2255, 0x2019,
- 0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000, 0x7003, 0x0000, 0x1078,
- 0x235e, 0x7004, 0xa084, 0x000f, 0x017e, 0x2009, 0x04fd, 0x210c,
- 0xa18a, 0x0005, 0x0048, 0x223a, 0x0038, 0x2240, 0xa085, 0x6280,
- 0x0078, 0x2242, 0x0028, 0x2240, 0xa085, 0x6280, 0x0078, 0x2242,
- 0xa085, 0x62c0, 0x017f, 0x7806, 0x780f, 0xb204, 0x7843, 0x00d8,
- 0x7853, 0x0080, 0x780b, 0x0008, 0x7047, 0x0008, 0x7053, 0x507f,
- 0x704f, 0x0000, 0x127f, 0x2000, 0x007c, 0x137e, 0x147e, 0x157e,
- 0x047e, 0x20a1, 0x012b, 0x2304, 0xa005, 0x789a, 0x0040, 0x2275,
- 0x8318, 0x2324, 0x8318, 0x2398, 0x24a8, 0xa484, 0xff00, 0x0040,
- 0x226d, 0xa482, 0x0100, 0x20a9, 0x0100, 0x2020, 0x53a6, 0xa005,
- 0x00c0, 0x2264, 0x3318, 0x0078, 0x225b, 0x047f, 0x157f, 0x147f,
- 0x137f, 0x007c, 0xa18c, 0x000f, 0x2011, 0x0101, 0x2204, 0xa084,
- 0xfff0, 0xa105, 0x2012, 0x1078, 0x235e, 0x007c, 0x2011, 0x0101,
- 0x20a9, 0x0009, 0x810b, 0x0070, 0x228f, 0x0078, 0x228a, 0xa18c,
- 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2009,
- 0x0101, 0x20a9, 0x0005, 0x8213, 0x0070, 0x22a0, 0x0078, 0x229b,
- 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x007c,
- 0x2011, 0x0101, 0x20a9, 0x000c, 0x810b, 0x0070, 0x22b1, 0x0078,
- 0x22ac, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012,
- 0x007c, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012,
- 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100,
- 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080,
- 0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa084, 0xffdf,
- 0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e,
- 0x2061, 0x0100, 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae, 0x0c7f,
- 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100,
- 0x609a, 0x60a4, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x0c7f,
- 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005, 0x0040,
- 0x233c, 0x2061, 0x7400, 0x1078, 0x2344, 0x0040, 0x2328, 0x20a9,
- 0x0000, 0x2061, 0x7300, 0x0c7e, 0x1078, 0x2344, 0x0040, 0x2318,
- 0x0c7f, 0x8c60, 0x0070, 0x2316, 0x0078, 0x230b, 0x0078, 0x233c,
- 0x007f, 0xa082, 0x7300, 0x2071, 0x5040, 0x7086, 0x7182, 0x2001,
- 0x0004, 0x706e, 0x7093, 0x000f, 0x1078, 0x21ac, 0x0078, 0x2338,
- 0x60c0, 0xa005, 0x00c0, 0x233c, 0x2071, 0x5040, 0x7182, 0x2c00,
- 0x708a, 0x2001, 0x0006, 0x706e, 0x7093, 0x000f, 0x1078, 0x21ac,
- 0x2001, 0x0000, 0x0078, 0x233e, 0x2001, 0x0001, 0x2091, 0x8001,
- 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040, 0x235b,
- 0x2060, 0x600c, 0xa306, 0x00c0, 0x2358, 0x6010, 0xa206, 0x00c0,
- 0x2358, 0x6014, 0xa106, 0x00c0, 0x2358, 0xa006, 0x0078, 0x235d,
- 0x6000, 0x0078, 0x2345, 0xa085, 0x0001, 0x007c, 0x2011, 0x5041,
- 0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204, 0xa084, 0x0100,
- 0x0040, 0x2374, 0x2021, 0xff04, 0x2122, 0x810b, 0x810b, 0x810b,
- 0x810b, 0xa18d, 0x0f00, 0x2104, 0x007c, 0x0e7e, 0x68e4, 0xa08c,
- 0x0020, 0x0040, 0x23c8, 0xa084, 0x0006, 0x00c0, 0x23c8, 0x6014,
- 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0f0, 0x5280,
- 0x7004, 0xa084, 0x000a, 0x00c0, 0x23c8, 0x7108, 0xa194, 0xff00,
- 0x0040, 0x23c8, 0xa18c, 0x00ff, 0x2001, 0x000c, 0xa106, 0x0040,
- 0x23af, 0x2001, 0x0012, 0xa106, 0x0040, 0x23b3, 0x2001, 0x0014,
- 0xa106, 0x0040, 0x23b7, 0x2001, 0x0019, 0xa106, 0x0040, 0x23bb,
- 0x2001, 0x0032, 0xa106, 0x0040, 0x23bf, 0x0078, 0x23c3, 0x2009,
- 0x0012, 0x0078, 0x23c5, 0x2009, 0x0014, 0x0078, 0x23c5, 0x2009,
- 0x0019, 0x0078, 0x23c5, 0x2009, 0x0020, 0x0078, 0x23c5, 0x2009,
- 0x003f, 0x0078, 0x23c5, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a,
- 0x0e7f, 0x007c, 0x0068, 0x23ca, 0x2091, 0x8000, 0x2071, 0x0000,
- 0x007e, 0x7018, 0xa084, 0x0001, 0x00c0, 0x23d1, 0x007f, 0x2071,
- 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x073f,
- 0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
- 0x0078, 0x23e8, 0x107e, 0x007e, 0x127e, 0x2091, 0x2300, 0x7f3c,
- 0x7e58, 0x7c30, 0x7d38, 0x77c2, 0x74c6, 0x76ca, 0x75ce, 0xa594,
- 0x003f, 0xa49c, 0x0003, 0xa484, 0x000f, 0x0079, 0x23ff, 0x2411,
- 0x2411, 0x2411, 0x274b, 0x3907, 0x240f, 0x2440, 0x244a, 0x240f,
- 0x240f, 0x240f, 0x240f, 0x240f, 0x240f, 0x240f, 0x240f, 0x1078,
- 0x23ca, 0x8507, 0xa084, 0x001f, 0x0079, 0x2416, 0x2454, 0x274b,
- 0x2905, 0x2a02, 0x2a2a, 0x2cc3, 0x2f6e, 0x2fb1, 0x2ffc, 0x3081,
- 0x3139, 0x31e2, 0x2440, 0x2827, 0x2f43, 0x2436, 0x3c78, 0x3c98,
- 0x3e5e, 0x3e6a, 0x3f3f, 0x2436, 0x2436, 0x4012, 0x4016, 0x3c76,
- 0x2436, 0x3dc9, 0x2436, 0x3b56, 0x244a, 0x2436, 0x1078, 0x23ca,
- 0x0018, 0x23ef, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c,
- 0x2019, 0x4cfd, 0x1078, 0x2255, 0x702f, 0x0001, 0x781b, 0x004f,
- 0x0078, 0x2438, 0x2019, 0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000,
- 0x781b, 0x00d5, 0x0078, 0x2438, 0x7242, 0x2009, 0x500f, 0x200b,
- 0x0000, 0xa584, 0x0001, 0x00c0, 0x3b6a, 0x0040, 0x2471, 0x1078,
- 0x23ca, 0x7003, 0x0000, 0x704b, 0x0000, 0x7043, 0x0000, 0x7037,
- 0x0000, 0x1078, 0x38de, 0x0018, 0x23ef, 0x2009, 0x500f, 0x200b,
- 0x0000, 0x7068, 0xa005, 0x00c0, 0x253c, 0x706c, 0xa084, 0x0007,
- 0x0079, 0x247a, 0x2573, 0x2482, 0x248e, 0x24ab, 0x24cd, 0x251a,
- 0x24f3, 0x2482, 0x1078, 0x38c6, 0x2009, 0x0048, 0x1078, 0x2e0f,
- 0x00c0, 0x248c, 0x7003, 0x0004, 0x0078, 0x2438, 0x1078, 0x38c6,
- 0x00c0, 0x24a9, 0x7080, 0x8007, 0x7882, 0x789b, 0x0010, 0x78ab,
- 0x000c, 0x789b, 0x0060, 0x78ab, 0x0001, 0x785b, 0x0004, 0x2009,
- 0x00e5, 0x1078, 0x2e03, 0x00c0, 0x24a9, 0x7003, 0x0004, 0x7093,
- 0x000f, 0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0, 0x24cb, 0x7180,
- 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, 0x00c0,
- 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, 0x785b,
- 0x0004, 0x2009, 0x00e5, 0x1078, 0x2e03, 0x00c0, 0x24cb, 0x7003,
- 0x0004, 0x7093, 0x000f, 0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0,
- 0x24f1, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f,
- 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0020, 0x7184, 0x79aa, 0x78ab,
- 0x000d, 0x789b, 0x0060, 0x78ab, 0x0004, 0x785b, 0x0004, 0x2009,
- 0x00e5, 0x1078, 0x2e03, 0x00c0, 0x24f1, 0x7003, 0x0004, 0x7093,
- 0x000f, 0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0, 0x2518, 0x7180,
- 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, 0x00c0,
- 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, 0x785b,
- 0x0004, 0x2009, 0x00e5, 0x1078, 0x2e03, 0x00c0, 0x2518, 0x7088,
- 0x708b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0002, 0x7093, 0x000f,
- 0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0, 0x2438, 0x7088, 0x2068,
- 0x6f14, 0x1078, 0x37bd, 0x2c50, 0x1078, 0x3978, 0x789b, 0x0010,
- 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x6e1c, 0x2041,
- 0x0001, 0x708c, 0xa084, 0x0400, 0x2001, 0x0004, 0x0040, 0x253a,
- 0x2001, 0x0006, 0x0078, 0x265b, 0x1078, 0x38c6, 0x00c0, 0x2438,
- 0x789b, 0x0010, 0x7068, 0x2068, 0x6f14, 0x1078, 0x37bd, 0x2c50,
- 0x1078, 0x3978, 0x6008, 0xa085, 0x0010, 0x600a, 0x6824, 0xa005,
- 0x0040, 0x255a, 0xa082, 0x0006, 0x0048, 0x2558, 0x0078, 0x255a,
- 0x6827, 0x0005, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0x7058,
- 0xa084, 0x8000, 0x0040, 0x2568, 0xa684, 0x0001, 0x0040, 0x256a,
- 0xa39c, 0xffbf, 0x7baa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001,
- 0x0003, 0x0078, 0x265b, 0x0018, 0x23ef, 0x744c, 0xa485, 0x0000,
- 0x0040, 0x258d, 0xa080, 0x5080, 0x2030, 0x7150, 0x8108, 0xa12a,
- 0x0048, 0x2584, 0x2009, 0x5080, 0x2164, 0x6504, 0x85ff, 0x00c0,
- 0x259e, 0x8421, 0x00c0, 0x257e, 0x7152, 0x7003, 0x0000, 0x704b,
- 0x0000, 0x7040, 0xa005, 0x0040, 0x3b6a, 0x0078, 0x2438, 0x764c,
- 0xa6b0, 0x5080, 0x7150, 0x2600, 0x0078, 0x2589, 0x7152, 0x2568,
- 0x2558, 0x754a, 0x2c50, 0x6034, 0xa085, 0x0000, 0x00c0, 0x259b,
- 0x6708, 0x773a, 0xa784, 0x033f, 0x0040, 0x25d4, 0xa784, 0x0021,
- 0x00c0, 0x259b, 0xa784, 0x0002, 0x0040, 0x25bd, 0xa784, 0x0004,
- 0x0040, 0x259b, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0008, 0x00c0,
- 0x259b, 0xa784, 0x0010, 0x00c0, 0x259b, 0xa784, 0x0200, 0x00c0,
- 0x259b, 0xa784, 0x0100, 0x0040, 0x25d4, 0x6018, 0xa005, 0x00c0,
- 0x259b, 0xa7bc, 0xfeff, 0x670a, 0x6823, 0x0000, 0x6e1c, 0xa684,
- 0x000e, 0x6118, 0x0040, 0x25e4, 0x601c, 0xa102, 0x0048, 0x25e7,
- 0x0040, 0x25e7, 0x0078, 0x2597, 0x81ff, 0x00c0, 0x2597, 0x68c3,
- 0x0000, 0xa784, 0x0080, 0x00c0, 0x25ef, 0x700c, 0x6022, 0xa7bc,
- 0xff7f, 0x670a, 0x1078, 0x3978, 0x0018, 0x23ef, 0x789b, 0x0010,
- 0xa046, 0x1078, 0x38c6, 0x00c0, 0x2438, 0x6b14, 0xa39c, 0x001f,
- 0xa39d, 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040, 0x260b, 0xa684,
- 0x0001, 0x0040, 0x260d, 0xa39c, 0xffbf, 0xa684, 0x0010, 0x0040,
- 0x2613, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684, 0x000e, 0x00c0,
- 0x261e, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x2659, 0x7158, 0xa18c,
- 0x0800, 0x0040, 0x33d7, 0x2011, 0x0020, 0xa684, 0x0008, 0x00c0,
- 0x262f, 0x8210, 0xa684, 0x0002, 0x00c0, 0x262f, 0x8210, 0x7aaa,
- 0x8840, 0x1078, 0x38de, 0x6a14, 0x610c, 0x8108, 0xa18c, 0x00ff,
- 0xa1e0, 0x7300, 0x2c64, 0x8cff, 0x0040, 0x2650, 0x6014, 0xa206,
- 0x00c0, 0x263a, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2635, 0x0c7e,
- 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f, 0x0078, 0x2573,
- 0x1078, 0x38c6, 0x00c0, 0x2438, 0x2a60, 0x610e, 0x79aa, 0x8840,
- 0x7132, 0x2001, 0x0001, 0x007e, 0x715c, 0xa184, 0x0018, 0x0040,
- 0x2676, 0xa184, 0x0010, 0x0040, 0x2669, 0x1078, 0x35d6, 0x00c0,
- 0x2699, 0xa184, 0x0008, 0x0040, 0x2676, 0x69a0, 0xa184, 0x0600,
- 0x00c0, 0x2676, 0x1078, 0x34c7, 0x0078, 0x2699, 0x69a0, 0xa184,
- 0x0800, 0x0040, 0x268d, 0x0c7e, 0x027e, 0x2960, 0x6000, 0xa085,
- 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106, 0x027f, 0x0c7f,
- 0x1078, 0x35d6, 0x00c0, 0x2699, 0x69a0, 0xa184, 0x0200, 0x0040,
- 0x2695, 0x1078, 0x3516, 0x0078, 0x2699, 0xa184, 0x0400, 0x00c0,
- 0x2672, 0x69a0, 0xa184, 0x1000, 0x0040, 0x26a4, 0x6914, 0xa18c,
- 0xff00, 0x810f, 0x1078, 0x22cd, 0x007f, 0x7002, 0xa68c, 0x00e0,
- 0xa684, 0x0060, 0x0040, 0x26b2, 0xa086, 0x0060, 0x00c0, 0x26b2,
- 0xa18d, 0x4000, 0x88ff, 0x0040, 0x26b7, 0xa18d, 0x0004, 0x795a,
- 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b, 0x0061, 0x6818,
- 0xa08d, 0x8000, 0xa084, 0x7fff, 0x691a, 0xa68c, 0x0080, 0x0040,
- 0x26d6, 0x7097, 0x0000, 0xa08a, 0x000d, 0x0050, 0x26d4, 0xa08a,
- 0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a, 0x78aa, 0x8008,
- 0x810c, 0x0040, 0x33dd, 0xa18c, 0x00f8, 0x00c0, 0x33dd, 0x157e,
- 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000, 0x80ac,
- 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814,
- 0x8007, 0x7882, 0x6d94, 0x7dd6, 0x7dde, 0x6e98, 0x7ed2, 0x7eda,
- 0x1078, 0x38c6, 0x00c0, 0x270d, 0x702c, 0x8003, 0x0048, 0x2706,
- 0x2019, 0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000, 0x7830, 0xa084,
- 0x00c0, 0x00c0, 0x270d, 0x0098, 0x2715, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x1078, 0x38de, 0x0078, 0x2461, 0x7200, 0xa284, 0x0007,
- 0xa086, 0x0001, 0x00c0, 0x2722, 0x781b, 0x004f, 0x1078, 0x38de,
- 0x0078, 0x2733, 0x6ab4, 0xa295, 0x2000, 0x7a5a, 0x781b, 0x004f,
- 0x1078, 0x38de, 0x7200, 0x2500, 0xa605, 0x0040, 0x2733, 0xa284,
- 0x0007, 0x1079, 0x2741, 0xad80, 0x0009, 0x7036, 0xa284, 0x0007,
- 0xa086, 0x0001, 0x00c0, 0x2438, 0x6018, 0x8000, 0x601a, 0x0078,
- 0x2438, 0x2749, 0x48f7, 0x48f7, 0x48e6, 0x48f7, 0x2749, 0x48e6,
- 0x2749, 0x1078, 0x23ca, 0x1078, 0x38c6, 0x0f7e, 0x2079, 0x5000,
- 0x78cc, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x276f, 0x706c, 0xa086,
- 0x0001, 0x00c0, 0x275e, 0x706e, 0x0078, 0x2802, 0x706c, 0xa086,
- 0x0005, 0x00c0, 0x276d, 0x7088, 0x2068, 0x681b, 0x0004, 0x6817,
- 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x706f, 0x0000, 0x2011,
- 0x0004, 0x716c, 0xa186, 0x0001, 0x0040, 0x2790, 0xa186, 0x0007,
- 0x00c0, 0x2780, 0x2009, 0x5038, 0x200b, 0x0005, 0x0078, 0x2790,
- 0x2009, 0x5013, 0x2104, 0x2009, 0x5012, 0x200a, 0x2009, 0x5038,
- 0x200b, 0x0001, 0x706f, 0x0000, 0x7073, 0x0001, 0x0078, 0x2792,
- 0x706f, 0x0000, 0x1078, 0x4633, 0x157e, 0x20a9, 0x0010, 0x2039,
- 0x0000, 0x1078, 0x36b0, 0xa7b8, 0x0100, 0x0070, 0x27a1, 0x0078,
- 0x2799, 0x157f, 0x7000, 0x0079, 0x27a5, 0x27d3, 0x27ba, 0x27ba,
- 0x27ad, 0x27d3, 0x27d3, 0x27d3, 0x27d3, 0x2021, 0x505a, 0x2404,
- 0xa005, 0x0040, 0x27d3, 0xad06, 0x00c0, 0x27ba, 0x6800, 0x2022,
- 0x0078, 0x27ca, 0x6820, 0xa084, 0x0001, 0x00c0, 0x27c6, 0x6f14,
- 0x1078, 0x37bd, 0x1078, 0x33ae, 0x0078, 0x27ca, 0x7060, 0x2060,
- 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008,
- 0x6822, 0x1078, 0x1c53, 0x2021, 0x7400, 0x1078, 0x280f, 0x2021,
- 0x505a, 0x1078, 0x280f, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7300,
- 0x1078, 0x280f, 0x8420, 0x0070, 0x27e7, 0x0078, 0x27e0, 0x2061,
- 0x5300, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6018, 0x6110, 0x81ff,
- 0x0040, 0x27f6, 0xa102, 0x0050, 0x27f6, 0x6012, 0x601b, 0x0000,
- 0xace0, 0x0010, 0x0070, 0x27fe, 0x0078, 0x27ed, 0x8421, 0x00c0,
- 0x27eb, 0x157f, 0x709c, 0xa084, 0x8000, 0x0040, 0x2809, 0x1078,
- 0x39cc, 0x7003, 0x0000, 0x704b, 0x0000, 0x0078, 0x2438, 0x047e,
- 0x2404, 0xa005, 0x0040, 0x2823, 0x2068, 0x6800, 0x007e, 0x6a1a,
- 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x1078, 0x1c53,
- 0x007f, 0x0078, 0x2811, 0x047f, 0x2023, 0x0000, 0x007c, 0xa282,
- 0x0003, 0x0050, 0x282d, 0x1078, 0x23ca, 0x2300, 0x0079, 0x2830,
- 0x2833, 0x28a6, 0x28c3, 0xa282, 0x0002, 0x0040, 0x2839, 0x1078,
- 0x23ca, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000, 0x0079, 0x2840,
- 0x2848, 0x2848, 0x284a, 0x287e, 0x33e3, 0x2848, 0x287e, 0x2848,
- 0x1078, 0x23ca, 0x7780, 0x1078, 0x36b0, 0x7780, 0xa7bc, 0x0f00,
- 0x1078, 0x37bd, 0x6018, 0xa005, 0x0040, 0x2875, 0x2021, 0x7400,
- 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x28de, 0x0040, 0x2875,
- 0x157e, 0x20a9, 0x0000, 0x2021, 0x7300, 0x047e, 0x2009, 0x0004,
- 0x2011, 0x0010, 0x1078, 0x28de, 0x047f, 0x0040, 0x2874, 0x8420,
- 0x0070, 0x2874, 0x0078, 0x2865, 0x157f, 0x8738, 0xa784, 0x001f,
- 0x00c0, 0x2850, 0x0078, 0x2461, 0x0078, 0x2461, 0x7780, 0x1078,
- 0x37bd, 0x6018, 0xa005, 0x0040, 0x28a4, 0x2021, 0x7400, 0x2009,
- 0x0005, 0x2011, 0x0020, 0x1078, 0x28de, 0x0040, 0x28a4, 0x157e,
- 0x20a9, 0x0000, 0x2021, 0x7300, 0x047e, 0x2009, 0x0005, 0x2011,
- 0x0020, 0x1078, 0x28de, 0x047f, 0x0040, 0x28a3, 0x8420, 0x0070,
- 0x28a3, 0x0078, 0x2894, 0x157f, 0x0078, 0x2461, 0x2200, 0x0079,
- 0x28a9, 0x28ac, 0x28ae, 0x28ae, 0x1078, 0x23ca, 0x2009, 0x0012,
- 0x706c, 0xa086, 0x0002, 0x0040, 0x28b7, 0x2009, 0x000e, 0x6818,
- 0xa084, 0x8000, 0x0040, 0x28bd, 0x691a, 0x706f, 0x0000, 0x7073,
- 0x0001, 0x0078, 0x3854, 0x2200, 0x0079, 0x28c6, 0x28cb, 0x28ae,
- 0x28c9, 0x1078, 0x23ca, 0x1078, 0x4633, 0x7000, 0xa086, 0x0001,
- 0x00c0, 0x3373, 0x1078, 0x33c4, 0x6008, 0xa084, 0xffef, 0x600a,
- 0x1078, 0x3366, 0x0040, 0x3373, 0x0078, 0x2573, 0x2404, 0xa005,
- 0x0040, 0x2901, 0x2068, 0x2d04, 0x007e, 0x6814, 0xa706, 0x0040,
- 0x28ed, 0x2d20, 0x007f, 0x0078, 0x28df, 0x007f, 0x2022, 0x691a,
- 0x6817, 0x0000, 0x6820, 0xa205, 0x6822, 0x1078, 0x1c53, 0x6010,
- 0x8001, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x33c4,
- 0x007c, 0xa085, 0x0001, 0x0078, 0x2900, 0x2300, 0x0079, 0x2908,
- 0x290d, 0x290b, 0x29a6, 0x1078, 0x23ca, 0x78ec, 0xa084, 0x0001,
- 0x00c0, 0x2921, 0x7000, 0xa086, 0x0004, 0x00c0, 0x2919, 0x0078,
- 0x2944, 0x1078, 0x33c4, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078,
- 0x3373, 0x78e4, 0xa005, 0x00d0, 0x2944, 0x0018, 0x2438, 0x2008,
- 0xa084, 0x0030, 0x00c0, 0x2930, 0x781b, 0x004f, 0x0078, 0x2438,
- 0x78ec, 0xa084, 0x0003, 0x0040, 0x292c, 0x2100, 0xa084, 0x0007,
- 0x0079, 0x293a, 0x297d, 0x2988, 0x296e, 0x2942, 0x38b9, 0x38b9,
- 0x2942, 0x2997, 0x1078, 0x23ca, 0x7000, 0xa086, 0x0004, 0x00c0,
- 0x295e, 0x706c, 0xa086, 0x0002, 0x00c0, 0x2954, 0x2011, 0x0002,
- 0x2019, 0x0000, 0x0078, 0x2827, 0x706c, 0xa086, 0x0006, 0x0040,
- 0x294e, 0x706c, 0xa086, 0x0004, 0x0040, 0x294e, 0x79e4, 0xa184,
- 0x0030, 0x0040, 0x2968, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x296a,
- 0x0078, 0x2f43, 0x2001, 0x0003, 0x0078, 0x2cd7, 0x6818, 0xa084,
- 0x8000, 0x0040, 0x2975, 0x681b, 0x001d, 0x1078, 0x368f, 0x782b,
- 0x3008, 0x781b, 0x0056, 0x0078, 0x2438, 0x6818, 0xa084, 0x8000,
- 0x0040, 0x2984, 0x681b, 0x001d, 0x1078, 0x368f, 0x0078, 0x3884,
- 0x6818, 0xa084, 0x8000, 0x0040, 0x298f, 0x681b, 0x001d, 0x1078,
- 0x368f, 0x782b, 0x3008, 0x781b, 0x00d2, 0x0078, 0x2438, 0x6818,
- 0xa084, 0x8000, 0x0040, 0x299e, 0x681b, 0x001d, 0x1078, 0x368f,
- 0x782b, 0x3008, 0x781b, 0x0093, 0x0078, 0x2438, 0xa584, 0x000f,
- 0x00c0, 0x29c3, 0x7000, 0x0079, 0x29ad, 0x2461, 0x29b7, 0x29b5,
- 0x3373, 0x3373, 0x3373, 0x3373, 0x29b5, 0x1078, 0x23ca, 0x1078,
- 0x33c4, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x3366, 0x0040,
- 0x3373, 0x0078, 0x2573, 0x78e4, 0xa005, 0x00d0, 0x2944, 0x0018,
- 0x2944, 0x2008, 0xa084, 0x0030, 0x00c0, 0x29d2, 0x781b, 0x004f,
- 0x0078, 0x2438, 0x78ec, 0xa084, 0x0003, 0x0040, 0x29ce, 0x2100,
- 0xa184, 0x0007, 0x0079, 0x29dc, 0x29ee, 0x29f2, 0x29e6, 0x29e4,
- 0x38b9, 0x38b9, 0x29e4, 0x38af, 0x1078, 0x23ca, 0x1078, 0x3697,
- 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2438, 0x1078, 0x3697,
- 0x0078, 0x3884, 0x1078, 0x3697, 0x782b, 0x3008, 0x781b, 0x00d2,
- 0x0078, 0x2438, 0x1078, 0x3697, 0x782b, 0x3008, 0x781b, 0x0093,
- 0x0078, 0x2438, 0x2300, 0x0079, 0x2a05, 0x2a0a, 0x2a08, 0x2a0c,
- 0x1078, 0x23ca, 0x0078, 0x3081, 0x681b, 0x0008, 0x78a3, 0x0000,
- 0x79e4, 0xa184, 0x0030, 0x0040, 0x3081, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x3081, 0xa184, 0x0007, 0x0079, 0x2a1e, 0x2a26, 0x29f2,
- 0x296e, 0x3854, 0x38b9, 0x38b9, 0x2a26, 0x38af, 0x1078, 0x3868,
- 0x0078, 0x2438, 0xa282, 0x0005, 0x0050, 0x2a30, 0x1078, 0x23ca,
- 0x2300, 0x0079, 0x2a33, 0x2a36, 0x2c84, 0x2c92, 0x2200, 0x0079,
- 0x2a39, 0x2a53, 0x2a40, 0x2a53, 0x2a3e, 0x2c69, 0x1078, 0x23ca,
- 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0048,
- 0x366b, 0xa08a, 0x0004, 0x00c8, 0x366b, 0x0079, 0x2a4f, 0x366b,
- 0x366b, 0x366b, 0x3619, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080,
- 0x0040, 0x2a64, 0x0078, 0x366b, 0x7000, 0xa005, 0x00c0, 0x2a5a,
- 0x2011, 0x0004, 0x0078, 0x31f5, 0xa184, 0x00ff, 0xa08a, 0x0010,
- 0x00c8, 0x366b, 0x0079, 0x2a6c, 0x2a7e, 0x2a7c, 0x2a96, 0x2a9a,
- 0x2b55, 0x366b, 0x366b, 0x2b57, 0x366b, 0x366b, 0x2c65, 0x2c65,
- 0x366b, 0x366b, 0x366b, 0x2c67, 0x1078, 0x23ca, 0xa684, 0x1000,
- 0x0040, 0x2a8b, 0x2001, 0x0500, 0x8000, 0x8000, 0x783a, 0x781b,
- 0x0091, 0x0078, 0x2438, 0x6818, 0xa084, 0x8000, 0x0040, 0x2a94,
- 0x681b, 0x001d, 0x0078, 0x2a82, 0x0078, 0x3854, 0x681b, 0x001d,
- 0x0078, 0x367b, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, 0x2adb,
- 0x6820, 0xa084, 0x0001, 0x00c0, 0x2ae1, 0x6818, 0xa086, 0x0008,
- 0x00c0, 0x2aac, 0x681b, 0x0000, 0xa684, 0x0400, 0x0040, 0x2b51,
- 0xa684, 0x0080, 0x0040, 0x2ad7, 0x7097, 0x0000, 0x6818, 0xa084,
- 0x003f, 0xa08a, 0x000d, 0x0050, 0x2ad7, 0xa08a, 0x000c, 0x7196,
- 0x2001, 0x000c, 0x800c, 0x719a, 0x789b, 0x0061, 0x78aa, 0x157e,
- 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000, 0x80ac,
- 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x781b,
- 0x0058, 0x0078, 0x2438, 0xa684, 0x1000, 0x0040, 0x2ae1, 0x0078,
- 0x2438, 0xa684, 0x0060, 0x0040, 0x2b4d, 0xa684, 0x0800, 0x0040,
- 0x2b4d, 0xa684, 0x8000, 0x00c0, 0x2aef, 0x0078, 0x2b09, 0xa6b4,
- 0x7fff, 0x7e5a, 0x6eb6, 0x789b, 0x0076, 0x7aac, 0x79ac, 0x78ac,
- 0x801b, 0x00c8, 0x2afc, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291,
- 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303,
- 0x68ae, 0xa684, 0x4000, 0x0040, 0x2b11, 0xa6b4, 0xbfff, 0x7e5a,
- 0x6eb6, 0x7000, 0xa086, 0x0003, 0x00c0, 0x2b1e, 0x1078, 0x46e9,
- 0x1078, 0x48e6, 0x781b, 0x0064, 0x0078, 0x2438, 0xa006, 0x1078,
- 0x49ed, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040,
- 0x2b2d, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda,
- 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0, 0x2b3f, 0xa6b5,
- 0x4000, 0x7e5a, 0x6eb6, 0x781b, 0x0064, 0x0078, 0x2438, 0x781b,
- 0x0064, 0x2200, 0xa115, 0x00c0, 0x2b49, 0x1078, 0x48f7, 0x0078,
- 0x2438, 0x1078, 0x4942, 0x0078, 0x2438, 0x781b, 0x0065, 0x0078,
- 0x2438, 0x781b, 0x0058, 0x0078, 0x2438, 0x1078, 0x23ca, 0x0078,
- 0x2bb8, 0x6920, 0xa184, 0x0100, 0x0040, 0x2b6f, 0xa18c, 0xfeff,
- 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0xefff, 0x6002,
- 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078, 0x2ba7, 0xa184,
- 0x0200, 0x0040, 0x2ba7, 0xa18c, 0xfdff, 0x6922, 0x0c7e, 0x7054,
- 0x2060, 0x6000, 0xa084, 0xdfff, 0x6002, 0x6004, 0xa084, 0xffef,
- 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2ba7,
- 0x1078, 0x37b9, 0x1078, 0x34c7, 0x88ff, 0x0040, 0x2ba7, 0x789b,
- 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684,
- 0x0400, 0x00c0, 0x2ba1, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078,
- 0x2438, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x7e58,
- 0xa684, 0x0400, 0x00c0, 0x2bb0, 0x781b, 0x0058, 0x0078, 0x2438,
- 0x781b, 0x0065, 0x0078, 0x2438, 0x0078, 0x3673, 0x0078, 0x3673,
- 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x0040, 0x2bb6, 0x789b,
- 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0, 0x2bf6,
- 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x2bee, 0x0048,
- 0x2bd3, 0x0078, 0x2bf0, 0xa380, 0x0002, 0xa102, 0x00c8, 0x2bee,
- 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000,
- 0xa084, 0xefef, 0x6002, 0x6004, 0xa084, 0xffe5, 0x6006, 0x0c7f,
- 0x7e58, 0xa6b4, 0xfffb, 0x7e5a, 0x0078, 0x2ba8, 0x0078, 0x2b59,
- 0x24a8, 0x7aa8, 0x00f0, 0x2bf0, 0x0078, 0x2bc1, 0xa284, 0x00f0,
- 0xa086, 0x0020, 0x00c0, 0x2c56, 0x8318, 0x8318, 0x2300, 0xa102,
- 0x0040, 0x2c06, 0x0048, 0x2c06, 0x0078, 0x2c53, 0xa286, 0x0023,
- 0x0040, 0x2bb6, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684,
- 0xfff1, 0xa085, 0x0010, 0x2030, 0x7e5a, 0x6008, 0xa085, 0x0010,
- 0x600a, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f,
- 0xa184, 0x0010, 0x0040, 0x2c2a, 0x1078, 0x37b9, 0x1078, 0x35d6,
- 0x0078, 0x2c39, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008, 0x2c48,
- 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2ba7, 0x1078, 0x37b9, 0x1078,
- 0x34c7, 0x88ff, 0x0040, 0x2ba7, 0x789b, 0x0060, 0x2800, 0x78aa,
- 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2c4d, 0x782b,
- 0x3008, 0x781b, 0x0056, 0x0078, 0x2438, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x2438, 0x7aa8, 0x0078, 0x2bc1, 0x8318, 0x2300,
- 0xa102, 0x0040, 0x2c5f, 0x0048, 0x2c5f, 0x0078, 0x2bc1, 0xa284,
- 0x0080, 0x00c0, 0x367b, 0x0078, 0x3673, 0x0078, 0x367b, 0x0078,
- 0x366b, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001,
- 0x0040, 0x2c74, 0x1078, 0x23ca, 0x7aa8, 0xa294, 0x00ff, 0x78a8,
- 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x366b, 0x0079, 0x2c80,
- 0x366b, 0x3414, 0x366b, 0x356b, 0xa282, 0x0000, 0x00c0, 0x2c8a,
- 0x1078, 0x23ca, 0x1078, 0x368f, 0x782b, 0x3008, 0x781b, 0x0065,
- 0x0078, 0x2438, 0xa282, 0x0003, 0x00c0, 0x2c98, 0x1078, 0x23ca,
- 0xa484, 0x8000, 0x00c0, 0x2cbb, 0x706c, 0xa005, 0x0040, 0x2ca2,
- 0x1078, 0x23ca, 0x6f14, 0x7782, 0xa7bc, 0x0f00, 0x1078, 0x37bd,
- 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x00c0,
- 0x2ca6, 0x1078, 0x3693, 0x706f, 0x0002, 0x2009, 0x5038, 0x200b,
- 0x0009, 0x0078, 0x2cbd, 0x1078, 0x369f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x2438, 0xa282, 0x0004, 0x0050, 0x2cc9, 0x1078,
- 0x23ca, 0x2300, 0x0079, 0x2ccc, 0x2ccf, 0x2db8, 0x2deb, 0xa286,
- 0x0003, 0x0040, 0x2cd5, 0x1078, 0x23ca, 0x2001, 0x0000, 0x007e,
- 0x68c0, 0xa005, 0x0040, 0x2cde, 0x7003, 0x0003, 0x68a0, 0xa084,
- 0x2000, 0x0040, 0x2ce7, 0x6008, 0xa085, 0x0002, 0x600a, 0x007f,
- 0x703e, 0x7000, 0xa084, 0x0007, 0x0079, 0x2cee, 0x2461, 0x2cf8,
- 0x2cf8, 0x2eed, 0x2f29, 0x2461, 0x2f29, 0x2cf6, 0x1078, 0x23ca,
- 0xa684, 0x1000, 0x00c0, 0x2d00, 0x1078, 0x4633, 0x0040, 0x2d92,
- 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2d48, 0xa186, 0x0008, 0x00c0,
- 0x2d17, 0x1078, 0x33c4, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078,
- 0x3366, 0x0040, 0x2d48, 0x1078, 0x4633, 0x0078, 0x2d2f, 0xa186,
- 0x0028, 0x00c0, 0x2d48, 0x1078, 0x4633, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x6018, 0xa005, 0x0040, 0x2d2f, 0x8001, 0x601a, 0xa005,
- 0x0040, 0x2d2f, 0x8001, 0xa005, 0x0040, 0x2d2f, 0x601e, 0x6820,
- 0xa084, 0x0001, 0x0040, 0x2461, 0x6820, 0xa084, 0xfffe, 0x6822,
- 0x7060, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802,
- 0xa005, 0x2d00, 0x00c0, 0x2d45, 0x6002, 0x6006, 0x0078, 0x2461,
- 0x017e, 0x1078, 0x2e1c, 0x017f, 0xa684, 0xdf00, 0x681e, 0x682b,
- 0x0000, 0x6f14, 0x81ff, 0x0040, 0x2d92, 0xa186, 0x0002, 0x00c0,
- 0x2d92, 0xa684, 0x0800, 0x00c0, 0x2d65, 0xa684, 0x0060, 0x0040,
- 0x2d65, 0x78d8, 0x7adc, 0x682e, 0x6a32, 0x6820, 0xa084, 0x0800,
- 0x00c0, 0x2d92, 0x8717, 0xa294, 0x000f, 0x8213, 0x8213, 0x8213,
- 0xa290, 0x5280, 0xa290, 0x0000, 0x221c, 0xa384, 0x0100, 0x00c0,
- 0x2d7b, 0x0078, 0x2d81, 0x8210, 0x2204, 0xa085, 0x0018, 0x2012,
- 0x8211, 0xa384, 0x0400, 0x0040, 0x2d8e, 0x68a0, 0xa084, 0x0100,
- 0x00c0, 0x2d8e, 0x1078, 0x2ea0, 0x0078, 0x2461, 0x6008, 0xa085,
- 0x0002, 0x600a, 0x6916, 0x6818, 0xa084, 0x8000, 0x0040, 0x2d9a,
- 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x1078, 0x33b5, 0x1078,
- 0x33c4, 0x00c0, 0x2da7, 0x6008, 0xa084, 0xffef, 0x600a, 0x6820,
- 0xa084, 0x0001, 0x00c0, 0x2db0, 0x1078, 0x33ae, 0x0078, 0x2db4,
- 0x7060, 0x2060, 0x6800, 0x6002, 0x1078, 0x1c53, 0x0078, 0x2461,
- 0xa282, 0x0004, 0x0048, 0x2dbe, 0x1078, 0x23ca, 0x2200, 0x0079,
- 0x2dc1, 0x2dbc, 0x2dc5, 0x2dd2, 0x2dc5, 0x7000, 0xa086, 0x0005,
- 0x0040, 0x2dce, 0x1078, 0x368f, 0x782b, 0x3008, 0x781b, 0x0065,
- 0x0078, 0x2438, 0x7890, 0x8007, 0x8001, 0xa084, 0x0007, 0xa080,
- 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003, 0x0040,
- 0x2de7, 0xa186, 0x0000, 0x0040, 0x2de7, 0x0078, 0x366b, 0x781b,
- 0x0065, 0x0078, 0x2438, 0x6820, 0xa085, 0x0004, 0x6822, 0x82ff,
- 0x00c0, 0x2df6, 0x1078, 0x368f, 0x0078, 0x2dfd, 0x8211, 0x0040,
- 0x2dfb, 0x1078, 0x23ca, 0x1078, 0x369f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x2438, 0x702c, 0x8003, 0x0048, 0x2e0d, 0x2019,
- 0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000, 0x1078, 0x38de, 0x7830,
- 0xa084, 0x00c0, 0x00c0, 0x2e19, 0x0018, 0x2e19, 0x791a, 0xa006,
- 0x007c, 0xa085, 0x0001, 0x007c, 0xa684, 0x0060, 0x00c0, 0x2e26,
- 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e9f, 0xa684, 0x0800,
- 0x00c0, 0x2e48, 0x68b4, 0xa084, 0x4800, 0xa635, 0xa684, 0x0800,
- 0x00c0, 0x2e48, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x703c, 0xa005,
- 0x00c0, 0x2e40, 0x2200, 0xa105, 0x0040, 0x2e47, 0x703f, 0x0015,
- 0x7000, 0xa086, 0x0006, 0x0040, 0x2e47, 0x1078, 0x4633, 0x007c,
- 0xa684, 0x0020, 0x0040, 0x2e6a, 0xa684, 0x4000, 0x0040, 0x2e56,
- 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e40, 0x68b4, 0xa084,
- 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2e50, 0x703c, 0xa005,
- 0x00c0, 0x2e64, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x692e, 0x6a32,
- 0x0078, 0x2e40, 0xa684, 0x4000, 0x0040, 0x2e74, 0x682f, 0x0000,
- 0x6833, 0x0000, 0x0078, 0x2e40, 0x68b4, 0xa084, 0x4800, 0xa635,
- 0xa684, 0x4000, 0x00c0, 0x2e6e, 0x703c, 0xa005, 0x00c0, 0x2e82,
- 0x703f, 0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb, 0x00c8, 0x2e89,
- 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32,
- 0x2100, 0xa205, 0x00c0, 0x2e96, 0x0078, 0x2e40, 0x7000, 0xa086,
- 0x0006, 0x0040, 0x2e9f, 0x1078, 0x49ed, 0x0078, 0x2e40, 0x007c,
- 0x6008, 0xa085, 0x0200, 0x600a, 0xa384, 0x0200, 0x0040, 0x2eac,
- 0x6008, 0xa085, 0x0002, 0x600a, 0x681b, 0x0006, 0x688f, 0x0000,
- 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003,
- 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020,
- 0x68b3, 0x0000, 0x68af, 0x0000, 0x7000, 0x0079, 0x2ec7, 0x2461,
- 0x2ed1, 0x2eda, 0x2ecf, 0x2ecf, 0x2ecf, 0x2ecf, 0x2ecf, 0x1078,
- 0x23ca, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2eda, 0x1078, 0x33ae,
- 0x0078, 0x2ee0, 0x7060, 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60,
- 0x2021, 0x505a, 0x2404, 0xa005, 0x0040, 0x2ee9, 0x2020, 0x0078,
- 0x2ee2, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, 0x33b5, 0x1078,
- 0x33c4, 0x6008, 0xa084, 0xfdff, 0x600a, 0x682b, 0x0000, 0x789b,
- 0x000e, 0x6f14, 0x6817, 0x0002, 0x1078, 0x4a35, 0xa684, 0x0800,
- 0x0040, 0x2f06, 0x691c, 0xa18d, 0x2000, 0x691e, 0x6818, 0xa084,
- 0x8000, 0x0040, 0x2f16, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2f14,
- 0x681b, 0x001e, 0x0078, 0x2f16, 0x681b, 0x0000, 0x2021, 0x505a,
- 0x2404, 0xad06, 0x0040, 0x2f1d, 0x7460, 0x6800, 0x2022, 0x68c3,
- 0x0000, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x1c53, 0x0078,
- 0x2461, 0x1078, 0x2e1c, 0x682b, 0x0000, 0x2001, 0x000e, 0x6f14,
- 0x1078, 0x38e4, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xa084, 0x8000,
- 0x0040, 0x2f3c, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x706f,
- 0x0000, 0x0078, 0x2461, 0x7000, 0xa005, 0x00c0, 0x2f49, 0x0078,
- 0x2461, 0xa006, 0x1078, 0x4633, 0x6817, 0x0000, 0x681b, 0x0014,
- 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa085, 0x00ff,
- 0x6822, 0x7000, 0x0079, 0x2f5c, 0x2461, 0x2f66, 0x2f66, 0x2f68,
- 0x2f68, 0x2f68, 0x2f68, 0x2f64, 0x1078, 0x23ca, 0x1078, 0x33c4,
- 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x337e, 0x2300, 0x0079,
- 0x2f71, 0x2f74, 0x2f76, 0x2faf, 0x1078, 0x23ca, 0x7000, 0x0079,
- 0x2f79, 0x2461, 0x2f83, 0x2f83, 0x2f9e, 0x2f83, 0x2fab, 0x2f9e,
- 0x2f81, 0x1078, 0x23ca, 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0,
- 0x2f9a, 0xa6b4, 0xffdf, 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a,
- 0x681c, 0xa084, 0xffdf, 0x681e, 0x1078, 0x4633, 0x1078, 0x48f7,
- 0x0078, 0x3854, 0xa684, 0x2000, 0x0040, 0x2f8d, 0x6818, 0xa084,
- 0x8000, 0x0040, 0x2fab, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040,
- 0x2fab, 0x681b, 0x0007, 0x1078, 0x3868, 0x0078, 0x2438, 0x1078,
- 0x23ca, 0x2300, 0x0079, 0x2fb4, 0x2fb7, 0x2fb9, 0x2fec, 0x1078,
- 0x23ca, 0x7000, 0x0079, 0x2fbc, 0x2461, 0x2fc6, 0x2fc6, 0x2fe1,
- 0x2fc6, 0x2fe8, 0x2fe1, 0x2fc4, 0x1078, 0x23ca, 0xa684, 0x0060,
- 0xa086, 0x0060, 0x00c0, 0x2fdd, 0xa6b4, 0xffbf, 0xa6b4, 0xbfff,
- 0xa6b5, 0x2000, 0x7e5a, 0x681c, 0xa084, 0xffbf, 0x681e, 0x1078,
- 0x4633, 0x1078, 0x48f7, 0x0078, 0x3854, 0xa684, 0x2000, 0x0040,
- 0x2fd0, 0x6818, 0xa084, 0x8000, 0x0040, 0x2fe8, 0x681b, 0x0007,
- 0x781b, 0x00d2, 0x0078, 0x2438, 0x6820, 0xa085, 0x0004, 0x6822,
- 0x1078, 0x381f, 0xa6b5, 0x0800, 0x1078, 0x368f, 0x782b, 0x3008,
- 0x781b, 0x0065, 0x0078, 0x2438, 0x2300, 0x0079, 0x2fff, 0x3002,
- 0x3004, 0x3006, 0x1078, 0x23ca, 0x0078, 0x367b, 0xa684, 0x0400,
- 0x00c0, 0x302f, 0x79e4, 0xa184, 0x0020, 0x0040, 0x3016, 0x78ec,
- 0xa084, 0x0003, 0x0040, 0x3016, 0x782b, 0x3009, 0x789b, 0x0060,
- 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xa184, 0x0020,
- 0x0040, 0x3027, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x302b, 0x2001,
- 0x0014, 0x0078, 0x2cd7, 0xa184, 0x0007, 0x0079, 0x3067, 0x7a90,
- 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, 0x0040, 0x3065,
- 0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0, 0x3056, 0x7ba8,
- 0x7ba8, 0xa386, 0x0001, 0x00c0, 0x3049, 0x2009, 0xfff7, 0x0078,
- 0x304f, 0xa386, 0x0003, 0x00c0, 0x3056, 0x2009, 0xffef, 0x0c7e,
- 0x7054, 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060,
- 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920,
- 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3854, 0x297d,
- 0x2988, 0x3071, 0x3079, 0x306f, 0x306f, 0x3854, 0x3854, 0x1078,
- 0x23ca, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078,
- 0x385e, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078,
- 0x3854, 0x79e4, 0xa184, 0x0030, 0x0040, 0x308b, 0x78ec, 0xa084,
- 0x0003, 0x00c0, 0x30b2, 0x7000, 0xa086, 0x0004, 0x00c0, 0x30a5,
- 0x706c, 0xa086, 0x0002, 0x00c0, 0x309b, 0x2011, 0x0002, 0x2019,
- 0x0000, 0x0078, 0x2827, 0x706c, 0xa086, 0x0006, 0x0040, 0x3095,
- 0x706c, 0xa086, 0x0004, 0x0040, 0x3095, 0x7000, 0xa086, 0x0000,
- 0x0040, 0x2438, 0x6818, 0xa085, 0x8000, 0x681a, 0x2001, 0x0014,
- 0x0078, 0x2cd7, 0xa184, 0x0007, 0x0079, 0x30b6, 0x3854, 0x3854,
- 0x30be, 0x3854, 0x38b9, 0x38b9, 0x3854, 0x3854, 0xa684, 0x0080,
- 0x0040, 0x30ed, 0x7194, 0x81ff, 0x0040, 0x30ed, 0xa182, 0x000d,
- 0x00d0, 0x30ce, 0x7097, 0x0000, 0x0078, 0x30d3, 0xa182, 0x000c,
- 0x7096, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, 0x157e, 0x137e,
- 0x147e, 0x7098, 0x8114, 0xa210, 0x729a, 0xa080, 0x000b, 0xad00,
- 0x2098, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6,
- 0x147f, 0x137f, 0x157f, 0x0078, 0x385e, 0xa684, 0x0400, 0x00c0,
- 0x312e, 0x6820, 0xa084, 0x0001, 0x0040, 0x385e, 0xa68c, 0x0060,
- 0xa684, 0x0060, 0x0040, 0x3102, 0xa086, 0x0060, 0x00c0, 0x3102,
- 0xa18d, 0x4000, 0xa18c, 0xfffb, 0x795a, 0x69b6, 0x789b, 0x0060,
- 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xa085, 0x8000, 0x681a,
- 0x78aa, 0x8008, 0x810c, 0x0040, 0x33dd, 0xa18c, 0x00f8, 0x00c0,
- 0x33dd, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000,
- 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
- 0x157f, 0x6814, 0x8007, 0x7882, 0x0078, 0x385e, 0x6818, 0xa084,
- 0x8000, 0x0040, 0x3135, 0x681b, 0x0008, 0x781b, 0x00c8, 0x0078,
- 0x2438, 0x2300, 0x0079, 0x313c, 0x3141, 0x31e0, 0x313f, 0x1078,
- 0x23ca, 0x7000, 0xa084, 0x0007, 0x0079, 0x3146, 0x2461, 0x3150,
- 0x3185, 0x315b, 0x314e, 0x2461, 0x314e, 0x314e, 0x1078, 0x23ca,
- 0x681c, 0xa084, 0x2000, 0x0040, 0x3169, 0x6008, 0xa085, 0x0002,
- 0x600a, 0x0078, 0x3169, 0x68c0, 0xa005, 0x00c0, 0x3185, 0x6920,
- 0xa18d, 0x0001, 0x6922, 0x68c3, 0x0001, 0x6800, 0x706a, 0x0078,
- 0x317f, 0x6920, 0xa18d, 0x0001, 0x6922, 0x6800, 0x6006, 0xa005,
- 0x00c0, 0x3173, 0x6002, 0x681c, 0xa084, 0x000e, 0x0040, 0x317f,
- 0x7014, 0x68ba, 0x7130, 0xa188, 0x7300, 0x0078, 0x3181, 0x2009,
- 0x7400, 0x2104, 0x6802, 0x2d0a, 0x7162, 0x6eb6, 0xa684, 0x0060,
- 0x0040, 0x31de, 0xa684, 0x0800, 0x00c0, 0x3199, 0xa684, 0x7fff,
- 0x68b6, 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, 0x4633, 0x0078,
- 0x31de, 0xa684, 0x0020, 0x0040, 0x31ae, 0x68c0, 0xa005, 0x0040,
- 0x31a5, 0x1078, 0x4a35, 0x0078, 0x31a8, 0xa006, 0x1078, 0x49ed,
- 0x79d8, 0x7adc, 0x69aa, 0x6aa6, 0x0078, 0x31b4, 0x1078, 0x37ca,
- 0x69aa, 0x6aa6, 0x1078, 0x49ed, 0xa684, 0x8000, 0x0040, 0x31de,
- 0xa684, 0x7fff, 0x68b6, 0x2001, 0x0076, 0x1078, 0x38e4, 0x2010,
- 0x2001, 0x0078, 0x1078, 0x38e4, 0x2008, 0xa684, 0x0020, 0x00c0,
- 0x31d6, 0x2001, 0x007a, 0x1078, 0x38e4, 0x801b, 0x00c8, 0x31d1,
- 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100,
- 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x0078, 0x2461,
- 0x0078, 0x367b, 0x7037, 0x0000, 0xa282, 0x0006, 0x0050, 0x31ea,
- 0x1078, 0x23ca, 0x7000, 0xa084, 0x0007, 0x10c0, 0x398a, 0x2300,
- 0x0079, 0x31f2, 0x31f5, 0x321e, 0x3232, 0x2200, 0x0079, 0x31f8,
- 0x321c, 0x367b, 0x31fe, 0x321c, 0x324e, 0x3290, 0x7003, 0x0005,
- 0x2001, 0x7510, 0x2068, 0x704a, 0x157e, 0x20a9, 0x0031, 0x2003,
- 0x0000, 0x8000, 0x0070, 0x320e, 0x0078, 0x3207, 0x157f, 0xad80,
- 0x0009, 0x7036, 0x6817, 0x0000, 0x68b7, 0x0700, 0x6823, 0x0800,
- 0x6827, 0x0003, 0x0078, 0x366b, 0x1078, 0x23ca, 0x7003, 0x0005,
- 0x2001, 0x7510, 0x2068, 0x704a, 0xad80, 0x0009, 0x7036, 0x2200,
- 0x0079, 0x322a, 0x367b, 0x3230, 0x3230, 0x324e, 0x3230, 0x367b,
- 0x1078, 0x23ca, 0x7003, 0x0005, 0x2001, 0x7510, 0x2068, 0x704a,
- 0xad80, 0x0009, 0x7036, 0x2200, 0x0079, 0x323e, 0x3246, 0x3244,
- 0x3244, 0x3246, 0x3244, 0x3246, 0x1078, 0x23ca, 0x1078, 0x369f,
- 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x7003, 0x0002,
- 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f,
- 0xa215, 0x2069, 0x7400, 0x2d04, 0x2d08, 0x7162, 0x2068, 0xa005,
- 0x0040, 0x3269, 0x6814, 0xa206, 0x0040, 0x3285, 0x6800, 0x0078,
- 0x325c, 0x7003, 0x0005, 0x2001, 0x7510, 0x2068, 0x704a, 0x7036,
- 0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x327a,
- 0x0078, 0x3273, 0x157f, 0xad80, 0x0009, 0x7036, 0x6a16, 0x68b7,
- 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6820,
- 0xa084, 0x0c00, 0x0040, 0x32df, 0x1078, 0x3697, 0x0078, 0x32df,
- 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8,
- 0xa484, 0x001f, 0xa215, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0xa1e8,
- 0x7300, 0x2d04, 0x2d08, 0x7162, 0x2068, 0xa005, 0x0040, 0x32af,
- 0x6814, 0xa206, 0x0040, 0x32ca, 0x6800, 0x0078, 0x32a2, 0x7003,
- 0x0005, 0x2001, 0x7510, 0x2068, 0x704a, 0x157e, 0x20a9, 0x0031,
- 0x2003, 0x0000, 0x8000, 0x0070, 0x32bf, 0x0078, 0x32b8, 0x157f,
- 0xad80, 0x0009, 0x7036, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800,
- 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040,
- 0x32df, 0xa084, 0x0800, 0x0040, 0x32d9, 0x1078, 0x369b, 0x0078,
- 0x32df, 0x1078, 0x3697, 0x708b, 0x0000, 0x0078, 0x32df, 0x027e,
- 0x8207, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x5280,
- 0x2060, 0x7056, 0x6000, 0x705a, 0x6004, 0x705e, 0xa684, 0x0060,
- 0x0040, 0x3337, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0,
- 0x3319, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, 0xb7ff, 0x7e5a,
- 0xa684, 0x0060, 0xa086, 0x0060, 0x0040, 0x3337, 0x68c0, 0xa005,
- 0x0040, 0x3312, 0x7003, 0x0003, 0x682b, 0x0000, 0x1078, 0x48e6,
- 0x0078, 0x3314, 0x1078, 0x48f7, 0xa6b5, 0x2000, 0x7e5a, 0x0078,
- 0x3337, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040,
- 0x3337, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xa6b4, 0xbfff,
- 0x7e5a, 0x007e, 0x68c0, 0xa005, 0x007f, 0x0040, 0x3335, 0x7003,
- 0x0003, 0x1078, 0x48e6, 0x0078, 0x3337, 0x1078, 0x4942, 0x077f,
- 0x1078, 0x37bd, 0x2009, 0x0065, 0xa684, 0x0004, 0x0040, 0x3358,
- 0x78e4, 0xa084, 0x0030, 0x0040, 0x3350, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x3350, 0x782b, 0x3008, 0x2009, 0x0065, 0x0078, 0x3358,
- 0x0f7e, 0x2079, 0x5000, 0x1078, 0x4633, 0x0f7f, 0x0040, 0x2461,
- 0x791a, 0x2d00, 0x704a, 0x8207, 0xa084, 0x000f, 0x8003, 0x8003,
- 0x8003, 0xa080, 0x5280, 0x2048, 0x0078, 0x2438, 0x6020, 0xa005,
- 0x0040, 0x3372, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008, 0x600a,
- 0x7010, 0x6026, 0x007c, 0xa006, 0x1078, 0x4633, 0x6817, 0x0000,
- 0x681b, 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084,
- 0x0007, 0x0079, 0x3383, 0x2461, 0x338d, 0x338d, 0x33aa, 0x3395,
- 0x3393, 0x3395, 0x338b, 0x1078, 0x23ca, 0x1078, 0x33b5, 0x1078,
- 0x33ae, 0x1078, 0x1c53, 0x0078, 0x2461, 0x706c, 0x706f, 0x0000,
- 0x7093, 0x0000, 0x0079, 0x339c, 0x33a6, 0x33a6, 0x33a4, 0x33a4,
- 0x33a4, 0x33a6, 0x33a4, 0x33a6, 0x0079, 0x2840, 0x706f, 0x0000,
- 0x0078, 0x2461, 0x681b, 0x0000, 0x0078, 0x2eed, 0x6800, 0xa005,
- 0x00c0, 0x33b3, 0x6002, 0x6006, 0x007c, 0x6010, 0xa005, 0x0040,
- 0x33be, 0x8001, 0x00d0, 0x33be, 0x1078, 0x23ca, 0x6012, 0x6008,
- 0xa084, 0xffef, 0x600a, 0x007c, 0x6018, 0xa005, 0x0040, 0x33ca,
- 0x8001, 0x601a, 0x007c, 0x1078, 0x38de, 0x681b, 0x0018, 0x0078,
- 0x3401, 0x1078, 0x38de, 0x681b, 0x0019, 0x0078, 0x3401, 0x1078,
- 0x38de, 0x681b, 0x001a, 0x0078, 0x3401, 0x1078, 0x38de, 0x681b,
- 0x0003, 0x0078, 0x3401, 0x7780, 0x1078, 0x37bd, 0x7184, 0xa18c,
- 0x00ff, 0xa1e8, 0x7300, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0,
- 0x33f3, 0x0078, 0x2461, 0x6814, 0x7280, 0xa206, 0x0040, 0x33fb,
- 0x6800, 0x0078, 0x33ec, 0x6800, 0x200a, 0x681b, 0x0005, 0x708b,
- 0x0000, 0x1078, 0x33b5, 0x6820, 0xa084, 0x0001, 0x00c0, 0x340a,
- 0x1078, 0x33ae, 0x1078, 0x33c4, 0x681f, 0x0000, 0x6823, 0x0020,
- 0x1078, 0x1c53, 0x0078, 0x2461, 0xa282, 0x0003, 0x00c0, 0x366b,
- 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4, 0x00ff, 0x6920, 0xa18d,
- 0x0080, 0x6922, 0xa184, 0x0100, 0x0040, 0x3478, 0xa18c, 0xfeff,
- 0x6922, 0xa4a4, 0x00ff, 0x0040, 0x3462, 0xa482, 0x000c, 0x0048,
- 0x3435, 0x0040, 0x3435, 0x2021, 0x000c, 0x852b, 0x852b, 0x1078,
- 0x372e, 0x0040, 0x343f, 0x1078, 0x3531, 0x0078, 0x346b, 0x1078,
- 0x36e9, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078,
- 0x3558, 0x0c7f, 0x6920, 0xa18d, 0x0100, 0x6922, 0x7e58, 0xa6b5,
- 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x345c, 0x782b, 0x3008,
- 0x781b, 0x0056, 0x0078, 0x2438, 0x782b, 0x3008, 0x781b, 0x0065,
- 0x0078, 0x2438, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006,
- 0x1078, 0x3558, 0x0c7f, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x3474,
- 0x781b, 0x0058, 0x0078, 0x2438, 0x781b, 0x0065, 0x0078, 0x2438,
- 0x0c7e, 0x7054, 0x2060, 0x6100, 0xa18c, 0x1000, 0x0040, 0x34b8,
- 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x348c,
- 0x0040, 0x348c, 0x2011, 0x000c, 0x2400, 0xa202, 0x00c8, 0x3491,
- 0x2220, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0,
- 0x34a1, 0xa282, 0x0019, 0x00c8, 0x34a7, 0x2011, 0x0019, 0x0078,
- 0x34a7, 0xa282, 0x000c, 0x00c8, 0x34a7, 0x2011, 0x000c, 0x2200,
- 0xa502, 0x00c8, 0x34ac, 0x2228, 0x1078, 0x36ed, 0x852b, 0x852b,
- 0x1078, 0x372e, 0x0040, 0x34b8, 0x1078, 0x3531, 0x0078, 0x34bc,
- 0x1078, 0x36e9, 0x1078, 0x3558, 0x7858, 0xa085, 0x0004, 0x785a,
- 0x0c7f, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x0c7e,
- 0x2960, 0x6000, 0xa084, 0x1000, 0x00c0, 0x34df, 0x6010, 0xa084,
- 0x000f, 0x00c0, 0x34d9, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x0c7f,
- 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3506, 0x68a0,
- 0xa084, 0x0200, 0x00c0, 0x34d9, 0x6208, 0xa294, 0x00ff, 0x7018,
- 0xa086, 0x0028, 0x00c0, 0x34f4, 0xa282, 0x0019, 0x00c8, 0x34fa,
- 0x2011, 0x0019, 0x0078, 0x34fa, 0xa282, 0x000c, 0x00c8, 0x34fa,
- 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c,
- 0x0048, 0x3506, 0x0040, 0x3506, 0x2019, 0x000c, 0x78ab, 0x0001,
- 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005,
- 0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x2960,
- 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078,
- 0x3521, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa,
- 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f,
- 0x007c, 0x0c7e, 0x7154, 0x2160, 0x1078, 0x3538, 0x0c7f, 0x007c,
- 0x2008, 0xa084, 0xfff0, 0xa425, 0x7c86, 0x6018, 0x789a, 0x7cae,
- 0x6412, 0x78a4, 0xa084, 0xfff8, 0xa18c, 0x0007, 0xa105, 0x78a6,
- 0x6016, 0x788a, 0xa4a4, 0x000f, 0x8427, 0x8204, 0x8004, 0xa084,
- 0x00ff, 0xa405, 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006, 0x007c,
- 0x0c7e, 0x7054, 0x2060, 0x1078, 0x355f, 0x0c7f, 0x007c, 0x6018,
- 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084,
- 0xfff0, 0x7886, 0x007c, 0xa282, 0x0002, 0x00c0, 0x366b, 0x7aa8,
- 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0200, 0x0040, 0x35b4,
- 0xa18c, 0xfdff, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8,
- 0x366b, 0x1078, 0x35fd, 0x1078, 0x3558, 0xa980, 0x0001, 0x200c,
- 0x1078, 0x37b9, 0x1078, 0x34c7, 0x88ff, 0x0040, 0x35a7, 0x789b,
- 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684,
- 0x0400, 0x00c0, 0x35a1, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078,
- 0x2438, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x7e58,
- 0xa684, 0x0400, 0x00c0, 0x35b0, 0x781b, 0x0058, 0x0078, 0x2438,
- 0x781b, 0x0065, 0x0078, 0x2438, 0xa282, 0x0002, 0x00c8, 0x35bc,
- 0xa284, 0x0001, 0x0040, 0x35c6, 0x7154, 0xa188, 0x0000, 0x210c,
- 0xa18c, 0x2000, 0x00c0, 0x35c6, 0x2011, 0x0000, 0x1078, 0x36db,
- 0x1078, 0x35fd, 0x1078, 0x3558, 0x7858, 0xa085, 0x0004, 0x785a,
- 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x0c7e, 0x027e,
- 0x2960, 0x6000, 0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x35ed,
- 0x6014, 0xa084, 0x0040, 0x00c0, 0x35eb, 0xa18c, 0xffef, 0x6106,
- 0xa006, 0x0078, 0x35fa, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
- 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x6820, 0xa085,
- 0x0200, 0x6822, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7054, 0x2060,
- 0x1078, 0x3604, 0x0c7f, 0x007c, 0x82ff, 0x0040, 0x3609, 0x2011,
- 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, 0xffbf,
- 0xa205, 0x78a6, 0x788a, 0x6016, 0x6004, 0xa084, 0xffef, 0x6006,
- 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x3622, 0x007f,
- 0x0078, 0x3625, 0x007f, 0x0078, 0x3667, 0xa684, 0x0020, 0x0040,
- 0x3667, 0x7888, 0xa084, 0x0040, 0x0040, 0x3667, 0x7bb8, 0xa384,
- 0x003f, 0x831b, 0x00c8, 0x3635, 0x8000, 0xa005, 0x0040, 0x364b,
- 0x831b, 0x00c8, 0x363e, 0x8001, 0x0040, 0x3663, 0xa684, 0x4000,
- 0x0040, 0x364b, 0x78b8, 0x801b, 0x00c8, 0x3647, 0x8000, 0xa084,
- 0x003f, 0x00c0, 0x3663, 0xa6b4, 0xbfff, 0x7e5a, 0x79d8, 0x7adc,
- 0x2001, 0x0001, 0xa108, 0x00c8, 0x3657, 0xa291, 0x0000, 0x79d2,
- 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x49ed, 0x781b, 0x0064, 0x1078,
- 0x4872, 0x0078, 0x2438, 0x781b, 0x0064, 0x0078, 0x2438, 0x781b,
- 0x0065, 0x0078, 0x2438, 0x1078, 0x36a3, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x2438, 0x1078, 0x368f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x2438, 0x6827, 0x0002, 0x1078, 0x3697, 0x78e4,
- 0xa084, 0x0030, 0x0040, 0x2461, 0x78ec, 0xa084, 0x0003, 0x0040,
- 0x2461, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x2001,
- 0x0005, 0x0078, 0x36a5, 0x2001, 0x000c, 0x0078, 0x36a5, 0x2001,
- 0x0006, 0x0078, 0x36a5, 0x2001, 0x000d, 0x0078, 0x36a5, 0x2001,
- 0x0009, 0x0078, 0x36a5, 0x2001, 0x0007, 0x789b, 0x0010, 0x78aa,
- 0x789b, 0x0060, 0x78ab, 0x0001, 0xa6b5, 0x0004, 0x7e5a, 0x007c,
- 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0,
- 0x5280, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040,
- 0x36c9, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004, 0xa085, 0x0008,
- 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, 0x0040,
- 0x36d9, 0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0010,
- 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab,
- 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004,
- 0x007c, 0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab,
- 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b,
- 0x0060, 0x78ab, 0x0005, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff,
- 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0,
- 0x2001, 0x5046, 0x2004, 0xa082, 0x0028, 0x0040, 0x3717, 0x2021,
- 0x37a0, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078, 0x371d, 0x2021,
- 0x37ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064, 0x2404,
- 0xa084, 0xfff0, 0xa106, 0x0040, 0x372c, 0x8420, 0x2300, 0xa210,
- 0x0070, 0x372c, 0x0078, 0x371f, 0x157f, 0x007c, 0x157e, 0x2009,
- 0x5046, 0x210c, 0xa182, 0x0032, 0x0048, 0x3742, 0x0040, 0x3746,
- 0x2009, 0x3792, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032,
- 0x0078, 0x3758, 0xa182, 0x0028, 0x0040, 0x3750, 0x2009, 0x37a0,
- 0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064, 0x0078, 0x3758,
- 0x2009, 0x37ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064,
- 0x2200, 0xa502, 0x0040, 0x3768, 0x0048, 0x3768, 0x8108, 0x2300,
- 0xa210, 0x0070, 0x3765, 0x0078, 0x3758, 0x157f, 0xa006, 0x007c,
- 0x157f, 0xa582, 0x0064, 0x00c8, 0x3777, 0x7808, 0xa085, 0x0070,
- 0x780a, 0x7044, 0xa085, 0x0070, 0x7046, 0x0078, 0x3777, 0x78ec,
- 0xa084, 0x0300, 0x0040, 0x377f, 0x2104, 0x0078, 0x3790, 0x2104,
- 0xa09e, 0x1102, 0x00c0, 0x3790, 0x2001, 0x04fd, 0x2004, 0xa082,
- 0x0005, 0x0048, 0x378f, 0x2001, 0x1201, 0x0078, 0x3790, 0x2104,
- 0xa005, 0x007c, 0x1102, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404,
- 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07,
- 0x3202, 0x4202, 0x5202, 0x6202, 0x7202, 0x6605, 0x7605, 0x7805,
- 0x7a05, 0x7c05, 0x7e05, 0x7f05, 0x2202, 0x3202, 0x4202, 0x5202,
- 0x5404, 0x6404, 0x7404, 0x7604, 0x7804, 0x7a04, 0x7c04, 0x7e04,
- 0x7f04, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00, 0x800b,
- 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e0,
- 0x5300, 0x007c, 0x79d8, 0x7adc, 0x78d0, 0x801b, 0x00c8, 0x37d1,
- 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x007c, 0x0f7e,
- 0x2079, 0x0100, 0x2009, 0x5040, 0x2091, 0x8000, 0x2104, 0x0079,
- 0x37e1, 0x3817, 0x37eb, 0x37eb, 0x37eb, 0x37eb, 0x37eb, 0x37eb,
- 0x381b, 0x1078, 0x23ca, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
- 0x00c0, 0x37ed, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0,
- 0x37f4, 0x68b4, 0xa085, 0x4000, 0x68b6, 0x7858, 0xa085, 0x4000,
- 0x785a, 0x7830, 0xa084, 0x0080, 0x00c0, 0x3817, 0x0018, 0x3817,
- 0x681c, 0xa084, 0x0020, 0x00c0, 0x3815, 0x0e7e, 0x2071, 0x5040,
- 0x1078, 0x3868, 0x0e7f, 0x0078, 0x3817, 0x781b, 0x00d2, 0x2091,
- 0x8001, 0x0f7f, 0x007c, 0x1078, 0x3a42, 0x0078, 0x3817, 0x0c7e,
- 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0,
- 0x5280, 0x6004, 0xa084, 0x000a, 0x00c0, 0x3852, 0x6108, 0xa194,
- 0xff00, 0x0040, 0x3852, 0xa18c, 0x00ff, 0x2001, 0x0019, 0xa106,
- 0x0040, 0x3841, 0x2001, 0x0032, 0xa106, 0x0040, 0x3845, 0x0078,
- 0x3849, 0x2009, 0x0020, 0x0078, 0x384b, 0x2009, 0x003f, 0x0078,
- 0x384b, 0x2011, 0x0000, 0x2100, 0xa205, 0x600a, 0x6004, 0xa085,
- 0x0002, 0x6006, 0x0c7f, 0x007c, 0x781b, 0x0065, 0x0078, 0x2438,
- 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x781b, 0x0058,
- 0x0078, 0x2438, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2438,
- 0x2009, 0x5020, 0x210c, 0xa186, 0x0000, 0x0040, 0x387c, 0xa186,
- 0x0001, 0x0040, 0x387f, 0x2009, 0x5038, 0x200b, 0x000b, 0x706f,
- 0x0001, 0x781b, 0x0048, 0x007c, 0x781b, 0x00cc, 0x007c, 0x2009,
- 0x5038, 0x200b, 0x000a, 0x007c, 0x2009, 0x5020, 0x210c, 0xa186,
- 0x0000, 0x0040, 0x389f, 0xa186, 0x0001, 0x0040, 0x3899, 0x2009,
- 0x5038, 0x200b, 0x000b, 0x706f, 0x0001, 0x781b, 0x0048, 0x0078,
- 0x2438, 0x2009, 0x5038, 0x200b, 0x000a, 0x0078, 0x2438, 0x782b,
- 0x3008, 0x781b, 0x00cc, 0x0078, 0x2438, 0x781b, 0x00d2, 0x0078,
- 0x2438, 0x782b, 0x3008, 0x781b, 0x00d2, 0x0078, 0x2438, 0x781b,
- 0x0093, 0x0078, 0x2438, 0x782b, 0x3008, 0x781b, 0x0093, 0x0078,
- 0x2438, 0x6818, 0xa084, 0x8000, 0x0040, 0x38c0, 0x681b, 0x001d,
- 0x706f, 0x0001, 0x781b, 0x0048, 0x0078, 0x2438, 0x007e, 0x7830,
- 0xa084, 0x00c0, 0x00c0, 0x38dc, 0x7808, 0xa084, 0xfffc, 0x780a,
- 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040,
- 0x38dc, 0x7044, 0x780a, 0xa005, 0x007f, 0x007c, 0x7044, 0xa085,
- 0x0002, 0x7046, 0x780a, 0x007c, 0x007e, 0x7830, 0xa084, 0x0040,
- 0x00c0, 0x38e5, 0x0098, 0x38f0, 0x007f, 0x789a, 0x78ac, 0x007c,
- 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005,
- 0x78ec, 0xa084, 0x0021, 0x0040, 0x38ff, 0x0098, 0x38fd, 0x007f,
- 0x789a, 0x78ac, 0x007e, 0x7044, 0x780a, 0x007f, 0x007c, 0x78ec,
- 0xa084, 0x0002, 0x00c0, 0x461d, 0xa784, 0x007d, 0x00c0, 0x3913,
- 0x2700, 0x1078, 0x23ca, 0xa784, 0x0001, 0x00c0, 0x2f43, 0xa784,
- 0x0070, 0x0040, 0x3923, 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x2375,
- 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040, 0x3930, 0x784b,
- 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2461, 0x0078, 0x3854,
- 0xa784, 0x0004, 0x0040, 0x3963, 0x78b8, 0xa084, 0x4001, 0x0040,
- 0x3963, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2461,
- 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0, 0x3963, 0x78c0,
- 0xa085, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00d2, 0x0078, 0x2438,
- 0x784b, 0x0008, 0x6818, 0xa084, 0x8000, 0x0040, 0x395f, 0x681b,
- 0x0015, 0xa684, 0x4000, 0x0040, 0x395f, 0x681b, 0x0007, 0x1078,
- 0x3868, 0x0078, 0x2438, 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00,
- 0x681e, 0x682f, 0x0000, 0x6833, 0x0000, 0x784b, 0x0008, 0x78ec,
- 0xa084, 0x0003, 0x0040, 0x2944, 0x0018, 0x2438, 0x0078, 0x3673,
- 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080,
- 0x5280, 0x2060, 0x2048, 0x7056, 0x6000, 0x705a, 0x6004, 0x705e,
- 0x2a60, 0x007c, 0x0079, 0x398c, 0x3994, 0x3995, 0x3994, 0x3997,
- 0x3994, 0x3994, 0x3994, 0x399c, 0x007c, 0x1078, 0x33c4, 0x1078,
- 0x4633, 0x7038, 0x600a, 0x007c, 0x70a0, 0xa005, 0x0040, 0x39a9,
- 0x2068, 0x1078, 0x1b45, 0x1078, 0x45b5, 0x1078, 0x45bc, 0x70a3,
- 0x0000, 0x007c, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x5040, 0x7000,
- 0xa086, 0x0007, 0x00c0, 0x39c0, 0x6110, 0x70bc, 0xa106, 0x00c0,
- 0x39c0, 0x0e7f, 0x1078, 0x1b52, 0x1078, 0x39c6, 0xa006, 0x007c,
- 0x2091, 0x8001, 0x0e7f, 0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e,
- 0x2071, 0x5040, 0x0078, 0x21d9, 0x785b, 0x0000, 0x70af, 0x000e,
- 0x2009, 0x0100, 0x017e, 0x70a0, 0xa06d, 0x0040, 0x39db, 0x70a3,
- 0x0000, 0x0078, 0x39e1, 0x70b3, 0x0000, 0x1078, 0x1b6e, 0x0040,
- 0x39e7, 0x70ac, 0x6826, 0x1078, 0x3ac2, 0x0078, 0x39db, 0x017f,
- 0x157e, 0x0c7e, 0x0d7e, 0x20a9, 0x0008, 0x2061, 0x7410, 0x6000,
- 0xa105, 0x6002, 0x601c, 0xa06d, 0x0040, 0x39ff, 0x6800, 0x601e,
- 0x1078, 0x193d, 0x6008, 0x8000, 0x600a, 0x0078, 0x39f2, 0x6018,
- 0xa06d, 0x0040, 0x3a09, 0x6800, 0x601a, 0x1078, 0x193d, 0x0078,
- 0x39ff, 0xace0, 0x0008, 0x0070, 0x3a0f, 0x0078, 0x39ef, 0x709c,
- 0xa084, 0x8000, 0x0040, 0x3a16, 0x1078, 0x3b3c, 0x0d7f, 0x0c7f,
- 0x157f, 0x007c, 0x127e, 0x2091, 0x2300, 0x6804, 0xa084, 0x000f,
- 0x0079, 0x3a22, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a32,
- 0x3a34, 0x3a3a, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a3c,
- 0x3a32, 0x3a34, 0x1078, 0x23ca, 0x1078, 0x4466, 0x1078, 0x193d,
- 0x0078, 0x3a40, 0x6827, 0x000b, 0x1078, 0x4466, 0x1078, 0x3ac2,
- 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x0098, 0x3a5e, 0x7830,
- 0xa084, 0x00c0, 0x00c0, 0x3a5e, 0x0d7e, 0x1078, 0x45c5, 0x2d00,
- 0x682e, 0x2009, 0x0004, 0x2001, 0x0000, 0x6827, 0x0084, 0x1078,
- 0x457e, 0x1078, 0x3ac2, 0x0d7f, 0x0078, 0x3a90, 0x7948, 0xa185,
- 0x4000, 0x784a, 0x0098, 0x3a67, 0x794a, 0x0078, 0x3a4c, 0x7828,
- 0xa086, 0x1834, 0x00c0, 0x3a70, 0xa185, 0x0004, 0x0078, 0x3a77,
- 0x7828, 0xa186, 0x1814, 0x00c0, 0x3a64, 0xa185, 0x000c, 0x784a,
- 0x789b, 0x000e, 0x78ab, 0x0002, 0x7858, 0xa084, 0x00ff, 0xa085,
- 0x0400, 0x785a, 0x70b4, 0xa080, 0x0091, 0x781a, 0x6827, 0x0002,
- 0x6827, 0x0084, 0x2009, 0x0004, 0x2001, 0x0000, 0x1078, 0x457e,
- 0x127f, 0x007c, 0x0d7e, 0x6b14, 0x1078, 0x1be0, 0x0040, 0x3a9f,
- 0x2068, 0x6827, 0x0002, 0x1078, 0x3ac2, 0x0078, 0x3a94, 0x0d7f,
- 0x007c, 0x0d7e, 0x6b14, 0x6c28, 0xa4a4, 0x00ff, 0x1078, 0x1b7e,
- 0x0040, 0x3aaf, 0x2068, 0x6827, 0x0002, 0x1078, 0x3ac2, 0x0d7f,
- 0x007c, 0x0d7e, 0x6b14, 0xa39c, 0x00ff, 0x1078, 0x1bb1, 0x0040,
- 0x3ac0, 0x2068, 0x6827, 0x0002, 0x1078, 0x3ac2, 0x0078, 0x3ab5,
- 0x0d7f, 0x007c, 0x0c7e, 0x6914, 0x1078, 0x3b33, 0x6904, 0xa18c,
- 0x00ff, 0xa186, 0x0006, 0x0040, 0x3add, 0xa186, 0x000d, 0x0040,
- 0x3afc, 0xa186, 0x0017, 0x00c0, 0x3ad9, 0x1078, 0x193d, 0x0078,
- 0x3adb, 0x1078, 0x1c55, 0x0c7f, 0x007c, 0x6004, 0x8001, 0x0048,
- 0x3afa, 0x6006, 0x2009, 0x0000, 0xa684, 0x0001, 0x00c0, 0x3aea,
- 0xa18d, 0x8000, 0xa684, 0x0004, 0x0040, 0x3af0, 0xa18d, 0x0002,
- 0x691e, 0x6823, 0x0000, 0x7104, 0x810f, 0x6818, 0xa105, 0x681a,
- 0x0078, 0x3ad9, 0x1078, 0x23ca, 0x6018, 0xa005, 0x00c0, 0x3b0b,
- 0x6008, 0x8001, 0x0048, 0x3b0b, 0x600a, 0x601c, 0x6802, 0x2d00,
- 0x601e, 0x0078, 0x3b21, 0xac88, 0x0006, 0x2104, 0xa005, 0x0040,
- 0x3b14, 0x2008, 0x0078, 0x3b0d, 0x6802, 0x2d0a, 0x6008, 0x8001,
- 0x0048, 0x3adb, 0x600a, 0x6018, 0x2068, 0x6800, 0x601a, 0x0078,
- 0x3b05, 0x157e, 0x137e, 0x147e, 0x0c7e, 0x0d7e, 0x1078, 0x191a,
- 0x2da0, 0x137f, 0x20a9, 0x0031, 0x53a3, 0x0c7f, 0x147f, 0x137f,
- 0x157f, 0x0078, 0x3ad9, 0xa184, 0x001f, 0x8003, 0x8003, 0x8003,
- 0xa080, 0x7410, 0x2060, 0x007c, 0x2019, 0x5051, 0x2304, 0xa085,
- 0x0001, 0x201a, 0x2019, 0x0102, 0x2304, 0xa085, 0x0001, 0x201a,
- 0x007c, 0x2019, 0x5051, 0x2304, 0xa084, 0xfffe, 0x201a, 0x2019,
- 0x0102, 0x2304, 0xa084, 0xfffe, 0x201a, 0x007c, 0x7990, 0xa18c,
- 0xfff8, 0x7992, 0x70b4, 0xa080, 0x00d8, 0x781a, 0x0078, 0x2438,
- 0x70a3, 0x0000, 0x7003, 0x0000, 0x7043, 0x0001, 0x7037, 0x0000,
- 0x0018, 0x23ef, 0x1078, 0x1b6e, 0x0040, 0x3b91, 0x2009, 0x500f,
- 0x200b, 0x0000, 0x68bc, 0x2060, 0x6100, 0xa184, 0x0300, 0x0040,
- 0x3b85, 0x6827, 0x000e, 0xa084, 0x0200, 0x0040, 0x3b81, 0x6827,
- 0x0017, 0x1078, 0x3ac2, 0x0078, 0x3b60, 0x7000, 0xa086, 0x0007,
- 0x00c0, 0x3be3, 0x2d00, 0x70a2, 0xad80, 0x000f, 0x7036, 0x0078,
- 0x3b98, 0x7040, 0xa086, 0x0001, 0x0040, 0x2471, 0x0078, 0x2438,
- 0x2031, 0x0000, 0x691c, 0xa184, 0x0002, 0x0040, 0x3ba1, 0xa6b5,
- 0x0004, 0xa184, 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3c72,
- 0x2004, 0xa635, 0x6820, 0xa084, 0x0400, 0x0040, 0x3bb9, 0x789b,
- 0x0018, 0x78ab, 0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5,
- 0x1000, 0x6820, 0xa084, 0x8000, 0x0040, 0x3bc5, 0xa6b5, 0x0400,
- 0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0xa684, 0x0200, 0x0040,
- 0x3bdf, 0x682c, 0x78d2, 0x6830, 0x78d6, 0xa684, 0x0100, 0x0040,
- 0x3bdd, 0x682c, 0xa084, 0x0001, 0x0040, 0x3bdd, 0x7888, 0xa084,
- 0x0040, 0x0040, 0x3bdd, 0xa6b5, 0x8000, 0x1078, 0x45ad, 0x7e5a,
- 0x6eb6, 0x0078, 0x45e4, 0x1078, 0x38c6, 0x00c0, 0x3c6c, 0x702c,
- 0x8004, 0x0048, 0x3bf1, 0x2019, 0x4cfd, 0x1078, 0x2255, 0x702f,
- 0x0001, 0x2011, 0x0001, 0x2031, 0x1000, 0x789b, 0x0018, 0x6814,
- 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x691c, 0xa184, 0x0002,
- 0x0040, 0x3c0a, 0xa6b5, 0x0004, 0x78ab, 0x0020, 0x6828, 0x78aa,
- 0xa290, 0x0002, 0x6820, 0xa084, 0x8000, 0x0040, 0x3c18, 0xa6b5,
- 0x0400, 0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0x0078, 0x3c26,
- 0x681c, 0xa084, 0x8000, 0x00c0, 0x3c26, 0xa6b5, 0x0800, 0x6820,
- 0xa084, 0x0100, 0x0040, 0x3c26, 0xa6b5, 0x4000, 0x681c, 0xa084,
- 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3c72, 0x2004, 0xa635,
- 0xa684, 0x0100, 0x0040, 0x3c40, 0x682c, 0xa084, 0x0001, 0x0040,
- 0x3c40, 0x7888, 0xa084, 0x0040, 0x0040, 0x3c40, 0xa6b5, 0x8000,
- 0x789b, 0x007e, 0x7eae, 0x6eb6, 0x6814, 0x8007, 0x78aa, 0x7882,
- 0x7aaa, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3c6c, 0x0018, 0x3c6c,
- 0x70b4, 0xa080, 0x00dd, 0x781a, 0x1078, 0x38de, 0xa684, 0x0200,
- 0x0040, 0x3c60, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x1078, 0x45ad,
- 0x2d00, 0x70a2, 0x704a, 0x6810, 0x70be, 0x7003, 0x0007, 0xad80,
- 0x000f, 0x7036, 0x0078, 0x2438, 0x1078, 0x1b45, 0x1078, 0x38de,
- 0x0078, 0x2438, 0x0000, 0x0300, 0x0200, 0x0000, 0x1078, 0x23ca,
- 0x2300, 0x0079, 0x3c7b, 0x3c7e, 0x3c7e, 0x3c80, 0x1078, 0x23ca,
- 0x1078, 0x45bc, 0x6924, 0xa184, 0x00ff, 0xa086, 0x000a, 0x0040,
- 0x3c92, 0xa184, 0xff00, 0xa085, 0x000a, 0x6826, 0x1078, 0x1b45,
- 0x0078, 0x3b60, 0x2001, 0x000a, 0x1078, 0x454c, 0x0078, 0x3b60,
- 0xa282, 0x0005, 0x0050, 0x3c9e, 0x1078, 0x23ca, 0x7000, 0xa084,
- 0x0007, 0x10c0, 0x398a, 0x1078, 0x191a, 0x00c0, 0x3cbd, 0xa684,
- 0x0004, 0x0040, 0x3caf, 0x2001, 0x2800, 0x0078, 0x3cb1, 0x2001,
- 0x0800, 0x71b4, 0xa188, 0x0091, 0x789b, 0x000e, 0x78aa, 0x2031,
- 0x0400, 0x7e5a, 0x791a, 0x0078, 0x2438, 0x6807, 0x0106, 0x680b,
- 0x0000, 0x689f, 0x0000, 0x6827, 0x0000, 0xa386, 0x0002, 0x00c0,
- 0x3cde, 0xa286, 0x0002, 0x00c0, 0x3cde, 0x78a0, 0xa005, 0x00c0,
- 0x3cde, 0xa484, 0x8000, 0x00c0, 0x3cde, 0x78e4, 0xa084, 0x0008,
- 0x0040, 0x3cde, 0xa6b5, 0x0008, 0x2019, 0x0000, 0x1078, 0x40d3,
- 0x2d00, 0x70a2, 0x704a, 0x7003, 0x0007, 0x7037, 0x0000, 0x6824,
- 0xa084, 0x0080, 0x0040, 0x3cf0, 0x1078, 0x4180, 0x0078, 0x2438,
- 0x2300, 0x0079, 0x3cf3, 0x3cf6, 0x3d77, 0x3d96, 0x2200, 0x0079,
- 0x3cf9, 0x3cfe, 0x3d0e, 0x3d34, 0x3d40, 0x3d63, 0x2029, 0x0001,
- 0xa026, 0x2011, 0x0000, 0x1078, 0x428d, 0x0079, 0x3d07, 0x3d0c,
- 0x2438, 0x3b60, 0x3d0c, 0x3d0c, 0x1078, 0x23ca, 0x7990, 0xa18c,
- 0x0007, 0x00c0, 0x3d15, 0x2009, 0x0008, 0x2011, 0x0001, 0xa684,
- 0x0004, 0x0040, 0x3d1d, 0x2011, 0x0003, 0x2220, 0xa12a, 0x2011,
- 0x0001, 0x1078, 0x428d, 0x0079, 0x3d25, 0x3d2a, 0x2438, 0x3b60,
- 0x3d32, 0x3d2c, 0x0078, 0x45ea, 0x70ab, 0x3d30, 0x0078, 0x2438,
- 0x0078, 0x3d2a, 0x1078, 0x23ca, 0xa684, 0x0010, 0x0040, 0x3d3e,
- 0x1078, 0x414f, 0x0040, 0x3d3e, 0x0078, 0x2438, 0x0078, 0x41bc,
- 0x6000, 0xa084, 0x0002, 0x0040, 0x3d5d, 0x70b4, 0xa080, 0x00cd,
- 0x781a, 0x0d7e, 0x1078, 0x45c5, 0x2d00, 0x682e, 0x6827, 0x0000,
- 0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x193d, 0x7003, 0x0000, 0x7037,
- 0x0000, 0x704b, 0x0000, 0x0078, 0x3b60, 0xa684, 0x0004, 0x00c0,
- 0x3d63, 0x0078, 0x45ea, 0x6000, 0xa084, 0x0004, 0x00c0, 0x3d75,
- 0x6000, 0xa084, 0x0001, 0x0040, 0x3d75, 0x70ab, 0x3d75, 0x2001,
- 0x0007, 0x1078, 0x4544, 0x0078, 0x45f0, 0x0078, 0x45ea, 0x2200,
- 0x0079, 0x3d7a, 0x3d7f, 0x3d7f, 0x3d7f, 0x3d81, 0x3d7f, 0x1078,
- 0x23ca, 0x70a7, 0x3d85, 0x0078, 0x45f6, 0x2011, 0x0018, 0x1078,
- 0x4287, 0x0079, 0x3d8b, 0x3d90, 0x2438, 0x3b60, 0x3d92, 0x3d94,
- 0x1078, 0x23ca, 0x1078, 0x23ca, 0x1078, 0x23ca, 0x2200, 0x0079,
- 0x3d99, 0x3d9e, 0x3da0, 0x3da0, 0x3d9e, 0x3d9e, 0x1078, 0x23ca,
- 0x78e4, 0xa084, 0x0008, 0x0040, 0x3db5, 0x70a7, 0x3da9, 0x0078,
- 0x45f6, 0x2011, 0x0004, 0x1078, 0x4287, 0x0079, 0x3daf, 0x3db5,
- 0x2438, 0x3b60, 0x3db5, 0x3dbf, 0x3dc3, 0x70ab, 0x3dbd, 0x2001,
- 0x0003, 0x1078, 0x4544, 0x0078, 0x45f0, 0x0078, 0x45ea, 0x70ab,
- 0x3db5, 0x0078, 0x2438, 0x70ab, 0x3dc7, 0x0078, 0x2438, 0x0078,
- 0x3dbd, 0xa282, 0x0003, 0x0050, 0x3dcf, 0x1078, 0x23ca, 0xa386,
- 0x0002, 0x00c0, 0x3de8, 0xa286, 0x0002, 0x00c0, 0x3dee, 0x78a0,
- 0xa005, 0x00c0, 0x3dee, 0xa484, 0x8000, 0x00c0, 0x3dee, 0x78e4,
- 0xa084, 0x0008, 0x0040, 0x3de8, 0xa6b5, 0x0008, 0x2019, 0x0000,
- 0xa684, 0x0008, 0x0040, 0x3dee, 0x1078, 0x412c, 0x6810, 0x70be,
- 0x7003, 0x0007, 0x2300, 0x0079, 0x3df5, 0x3df8, 0x3e25, 0x3e2d,
- 0x2200, 0x0079, 0x3dfb, 0x3e00, 0x3dfe, 0x3e19, 0x1078, 0x23ca,
- 0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011, 0x0001, 0x1078, 0x428d,
- 0x0079, 0x3e0a, 0x3e0f, 0x2438, 0x3b60, 0x3e17, 0x3e11, 0x0078,
- 0x45ea, 0x70ab, 0x3e15, 0x0078, 0x2438, 0x0078, 0x3e0f, 0x1078,
- 0x23ca, 0xa684, 0x0010, 0x0040, 0x3e23, 0x1078, 0x414f, 0x0040,
- 0x3e23, 0x0078, 0x2438, 0x0078, 0x41bc, 0x2200, 0x0079, 0x3e28,
- 0x3e2b, 0x3e2b, 0x3e2b, 0x1078, 0x23ca, 0x2200, 0x0079, 0x3e30,
- 0x3e33, 0x3e35, 0x3e35, 0x1078, 0x23ca, 0x78e4, 0xa084, 0x0008,
- 0x0040, 0x3e4a, 0x70a7, 0x3e3e, 0x0078, 0x45f6, 0x2011, 0x0004,
- 0x1078, 0x4287, 0x0079, 0x3e44, 0x3e4a, 0x2438, 0x3b60, 0x3e4a,
- 0x3e54, 0x3e58, 0x70ab, 0x3e52, 0x2001, 0x0003, 0x1078, 0x4544,
- 0x0078, 0x45f0, 0x0078, 0x45ea, 0x70ab, 0x3e4a, 0x0078, 0x2438,
- 0x70ab, 0x3e5c, 0x0078, 0x2438, 0x0078, 0x3e52, 0x2300, 0x0079,
- 0x3e61, 0x3e66, 0x3e68, 0x3e64, 0x1078, 0x23ca, 0x70a4, 0x007a,
- 0x70a4, 0x007a, 0xa282, 0x0002, 0x0050, 0x3e70, 0x1078, 0x23ca,
- 0xa684, 0x0200, 0x0040, 0x3e7a, 0x1078, 0x45b5, 0x1078, 0x426f,
- 0x1078, 0x45bc, 0x2300, 0x0079, 0x3e7d, 0x3e80, 0x3ea4, 0x3f0a,
- 0xa286, 0x0001, 0x0040, 0x3e86, 0x1078, 0x23ca, 0xa684, 0x0200,
- 0x0040, 0x3e8e, 0x1078, 0x45b5, 0x1078, 0x45bc, 0x2001, 0x0001,
- 0x1078, 0x454c, 0x78b8, 0xa084, 0xc001, 0x0040, 0x3ea0, 0x7848,
- 0xa085, 0x0008, 0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3e9b,
- 0x7003, 0x0000, 0x0078, 0x3b60, 0x2200, 0x0079, 0x3ea7, 0x3ea9,
- 0x3eda, 0x70a7, 0x3ead, 0x0078, 0x45f6, 0x2011, 0x000d, 0x1078,
- 0x4287, 0x0079, 0x3eb3, 0x3eba, 0x2438, 0x3b60, 0x3ec2, 0x3eca,
- 0x3ed0, 0x3ed2, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
- 0x0078, 0x45e4, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
- 0x0078, 0x45e4, 0x70ab, 0x3ece, 0x0078, 0x2438, 0x0078, 0x3eba,
- 0x1078, 0x23ca, 0x70ab, 0x3ed6, 0x0078, 0x2438, 0x1078, 0x45fc,
- 0x0078, 0x2438, 0x70a7, 0x3ede, 0x0078, 0x45f6, 0x2011, 0x0012,
- 0x1078, 0x4287, 0x0079, 0x3ee4, 0x3eea, 0x2438, 0x3b60, 0x3ef6,
- 0x3efe, 0x3f04, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
- 0x70b4, 0xa080, 0x00a5, 0x781a, 0x0078, 0x2438, 0xa6b4, 0x00ff,
- 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, 0x70ab, 0x3f02,
- 0x0078, 0x2438, 0x0078, 0x3eea, 0x70ab, 0x3f08, 0x0078, 0x2438,
- 0x0078, 0x3ef6, 0xa286, 0x0001, 0x0040, 0x3f10, 0x1078, 0x23ca,
- 0x70a7, 0x3f14, 0x0078, 0x45f6, 0x2011, 0x0015, 0x1078, 0x4287,
- 0x0079, 0x3f1a, 0x3f1f, 0x2438, 0x3b60, 0x3f2d, 0x3f39, 0xa6b4,
- 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x783b, 0x1301, 0x70b4,
- 0xa080, 0x00b5, 0x781a, 0x0078, 0x2438, 0xa6b4, 0x00ff, 0xa6b5,
- 0x0400, 0x6eb6, 0x7e5a, 0x70b4, 0xa080, 0x00a5, 0x781a, 0x0078,
- 0x2438, 0x70ab, 0x3f3d, 0x0078, 0x2438, 0x0078, 0x3f1f, 0xa282,
- 0x0003, 0x0050, 0x3f45, 0x1078, 0x23ca, 0x2300, 0x0079, 0x3f48,
- 0x3f4b, 0x3f82, 0x3fdd, 0xa286, 0x0001, 0x0040, 0x3f51, 0x1078,
- 0x23ca, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x3f5e,
- 0x1078, 0x3ac2, 0x7003, 0x0000, 0x0078, 0x3b60, 0x683b, 0x0000,
- 0x6837, 0x0000, 0xa684, 0x0200, 0x0040, 0x3f6c, 0x1078, 0x45b5,
- 0x1078, 0x426f, 0x1078, 0x45bc, 0x2001, 0x0001, 0x1078, 0x454c,
- 0x78b8, 0xa084, 0xc001, 0x0040, 0x3f7e, 0x7848, 0xa085, 0x0008,
- 0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3f79, 0x7003, 0x0000,
- 0x0078, 0x3b60, 0x2200, 0x0079, 0x3f85, 0x3f87, 0x3fb8, 0x70a7,
- 0x3f8b, 0x0078, 0x45f6, 0x2011, 0x000d, 0x1078, 0x4287, 0x0079,
- 0x3f91, 0x3f98, 0x2438, 0x3b60, 0x3fa0, 0x3fa8, 0x3fae, 0x3fb0,
- 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4,
- 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4,
- 0x70ab, 0x3fac, 0x0078, 0x2438, 0x0078, 0x3f98, 0x1078, 0x23ca,
- 0x70ab, 0x3fb4, 0x0078, 0x2438, 0x1078, 0x45fc, 0x0078, 0x2438,
- 0x70a7, 0x3fbc, 0x0078, 0x45f6, 0x2011, 0x0005, 0x1078, 0x4287,
- 0x0079, 0x3fc2, 0x3fc7, 0x2438, 0x3b60, 0x3fcf, 0x3fd7, 0xa6b4,
- 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, 0xa6b4,
- 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, 0x70ab,
- 0x3fdb, 0x0078, 0x2438, 0x0078, 0x3fc7, 0xa286, 0x0001, 0x0040,
- 0x3fe3, 0x1078, 0x23ca, 0x70a7, 0x3fe7, 0x0078, 0x45f6, 0x2011,
- 0x0006, 0x1078, 0x4287, 0x0079, 0x3fed, 0x3ff2, 0x2438, 0x3b60,
- 0x3ff8, 0x4002, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4,
- 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0xa6b5, 0x4000, 0x7e5a,
- 0x0078, 0x45e4, 0x70ab, 0x4006, 0x0078, 0x2438, 0x0078, 0x3ff2,
- 0x2300, 0x0079, 0x400b, 0x4010, 0x400e, 0x400e, 0x1078, 0x23ca,
- 0x1078, 0x23ca, 0x2300, 0x71a8, 0xa005, 0x017a, 0x6810, 0x70be,
- 0xa282, 0x0003, 0x0050, 0x401e, 0x1078, 0x23ca, 0x2300, 0x0079,
- 0x4021, 0x4024, 0x4037, 0x4059, 0x82ff, 0x00c0, 0x4029, 0x1078,
- 0x23ca, 0xa684, 0x0200, 0x0040, 0x4031, 0x1078, 0x45b5, 0x1078,
- 0x45bc, 0x2001, 0x0001, 0x1078, 0x454c, 0x0078, 0x2438, 0xa296,
- 0x0002, 0x0040, 0x4040, 0x82ff, 0x0040, 0x4040, 0x1078, 0x23ca,
- 0x70a7, 0x4044, 0x0078, 0x45f6, 0x2011, 0x0018, 0x1078, 0x4287,
- 0x0079, 0x404a, 0x404f, 0x2438, 0x3b60, 0x4051, 0x4053, 0x0078,
- 0x45e4, 0x0078, 0x45e4, 0x70ab, 0x4057, 0x0078, 0x2438, 0x0078,
- 0x404f, 0x2200, 0x0079, 0x405c, 0x405e, 0x4077, 0x70a7, 0x4062,
- 0x0078, 0x45f6, 0x2011, 0x0017, 0x1078, 0x4287, 0x0079, 0x4068,
- 0x406d, 0x2438, 0x3b60, 0x406f, 0x4071, 0x0078, 0x45e4, 0x0078,
- 0x45e4, 0x70ab, 0x4075, 0x0078, 0x2438, 0x0078, 0x406d, 0xa484,
- 0x8000, 0x00c0, 0x40c1, 0xa684, 0x0100, 0x0040, 0x408b, 0x1078,
- 0x45b5, 0x1078, 0x426f, 0x1078, 0x45bc, 0x7848, 0xa085, 0x000c,
- 0x784a, 0x0078, 0x408f, 0x78d8, 0x78d2, 0x78dc, 0x78d6, 0xa6b4,
- 0xefff, 0x7e5a, 0x70a7, 0x4096, 0x0078, 0x45f6, 0x2011, 0x000d,
- 0x1078, 0x4287, 0x0079, 0x409c, 0x40a3, 0x2438, 0x3b60, 0x40a3,
- 0x40b1, 0x40b7, 0x40b9, 0xa684, 0x0100, 0x0040, 0x40af, 0x1078,
- 0x4573, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x1078, 0x45ad, 0x0078,
- 0x45e4, 0x70ab, 0x40b5, 0x0078, 0x2438, 0x0078, 0x40a3, 0x1078,
- 0x23ca, 0x70ab, 0x40bd, 0x0078, 0x2438, 0x1078, 0x45fc, 0x0078,
- 0x2438, 0x1078, 0x45bc, 0x70ab, 0x40cb, 0x2001, 0x0003, 0x1078,
- 0x4544, 0x0078, 0x45f0, 0x1078, 0x45ad, 0x682c, 0x78d2, 0x6830,
- 0x78d6, 0x0078, 0x45e4, 0x70b8, 0x6812, 0x70be, 0x8000, 0x70ba,
- 0x681b, 0x0000, 0xa684, 0x0008, 0x0040, 0x40f6, 0x157e, 0x137e,
- 0x147e, 0x7890, 0x8004, 0x8004, 0x8004, 0x8004, 0xa084, 0x000f,
- 0x681a, 0x80ac, 0x789b, 0x0000, 0xaf80, 0x002b, 0x2098, 0xad80,
- 0x000b, 0x20a0, 0x53a5, 0x147f, 0x137f, 0x157f, 0xa6c4, 0x0f00,
- 0xa684, 0x0002, 0x00c0, 0x4102, 0x692c, 0x810d, 0x810d, 0x810d,
- 0x0078, 0x410f, 0x789b, 0x0010, 0x79ac, 0x0078, 0x410f, 0x017e,
- 0x2009, 0x0005, 0x2001, 0x3d00, 0x1078, 0x457e, 0x017f, 0xa184,
- 0x001f, 0xa805, 0x6816, 0x1078, 0x3b33, 0x68be, 0xa684, 0x0004,
- 0x0040, 0x4120, 0xa18c, 0xff00, 0x78a8, 0xa084, 0x00ff, 0xa105,
- 0x682a, 0xa6b4, 0x00ff, 0x6000, 0xa084, 0x0008, 0x0040, 0x412a,
- 0xa6b5, 0x4000, 0x6eb6, 0x007c, 0x157e, 0x137e, 0x147e, 0x6918,
- 0x7890, 0x8004, 0x8004, 0x8004, 0x8004, 0xa084, 0x000f, 0x007e,
- 0xa100, 0x681a, 0x007f, 0x8000, 0x8004, 0x0040, 0x414b, 0x20a8,
- 0x8104, 0xa080, 0x000b, 0xad00, 0x20a0, 0x789b, 0x0000, 0xaf80,
- 0x002b, 0x2098, 0x53a5, 0x147f, 0x137f, 0x157f, 0x007c, 0x682c,
- 0xa084, 0x0020, 0x00c0, 0x4157, 0x620c, 0x0078, 0x4158, 0x6210,
- 0x6b18, 0x2300, 0xa202, 0x0040, 0x4178, 0x2018, 0xa382, 0x000e,
- 0x0048, 0x4168, 0x0040, 0x4168, 0x2019, 0x000e, 0x0078, 0x416c,
- 0x7858, 0xa084, 0xffef, 0x785a, 0x783b, 0x1b01, 0x7893, 0x0000,
- 0x7ba2, 0x70b4, 0xa080, 0x008e, 0x781a, 0xa085, 0x0001, 0x007c,
- 0x7858, 0xa084, 0xffef, 0x785a, 0x7893, 0x0000, 0xa006, 0x007c,
- 0x6904, 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x418d, 0xa196,
- 0x000f, 0x0040, 0x418d, 0x6807, 0x0117, 0x6914, 0x1078, 0x3b33,
- 0x6100, 0x8104, 0x00c8, 0x41a8, 0x601c, 0xa005, 0x0040, 0x419c,
- 0x2001, 0x0800, 0x0078, 0x41aa, 0x0d7e, 0x6824, 0x007e, 0x1078,
- 0x45c5, 0x007f, 0x6826, 0x2d00, 0x682e, 0x1078, 0x3ac2, 0x0d7f,
- 0x2001, 0x0200, 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820,
- 0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a, 0x71b4,
- 0xa188, 0x0091, 0x791a, 0x007c, 0xa6c4, 0x0f00, 0xa684, 0x0002,
- 0x00c0, 0x41cf, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184, 0x001f,
- 0xa805, 0x6816, 0x1078, 0x3b33, 0x68be, 0x0078, 0x41d2, 0x6914,
- 0x1078, 0x3b33, 0x6100, 0x8104, 0x00c8, 0x421c, 0xa184, 0x0300,
- 0x0040, 0x41de, 0x6807, 0x0117, 0x0078, 0x41fc, 0x6004, 0xa005,
- 0x00c0, 0x4205, 0x6807, 0x0117, 0x601c, 0xa005, 0x00c0, 0x41f2,
- 0x0d7e, 0x1078, 0x45c5, 0x6827, 0x0034, 0x2d00, 0x682e, 0x1078,
- 0x3ac2, 0x0d7f, 0xa684, 0x0004, 0x0040, 0x41fc, 0x2031, 0x0400,
- 0x2001, 0x2800, 0x0078, 0x4200, 0x2031, 0x0400, 0x2001, 0x0800,
- 0x71b4, 0xa188, 0x0091, 0x0078, 0x424a, 0x6018, 0xa005, 0x00c0,
- 0x41f2, 0x601c, 0xa005, 0x00c0, 0x41f2, 0x689f, 0x0000, 0x6827,
- 0x003d, 0xa684, 0x0001, 0x0040, 0x4258, 0xa6b5, 0x0800, 0x71b4,
- 0xa188, 0x00ae, 0x0078, 0x4253, 0x6807, 0x0117, 0x2031, 0x0400,
- 0x692c, 0xa18c, 0x00ff, 0xa186, 0x0012, 0x00c0, 0x422d, 0x2001,
- 0x4265, 0x2009, 0x0001, 0x0078, 0x423e, 0xa186, 0x0003, 0x00c0,
- 0x4237, 0x2001, 0x4266, 0x2009, 0x0012, 0x0078, 0x423e, 0x2001,
- 0x0200, 0x71b4, 0xa188, 0x0091, 0x0078, 0x424a, 0x1078, 0x4598,
- 0x78a3, 0x0000, 0x681c, 0xa085, 0x0040, 0x681e, 0x71b4, 0xa188,
- 0x00da, 0xa006, 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820,
- 0xa085, 0x8000, 0x6822, 0x6eb6, 0x7e5a, 0x791a, 0x0078, 0x2438,
- 0x6eb6, 0x1078, 0x3ac2, 0x6810, 0x70be, 0x7003, 0x0007, 0x70a3,
- 0x0000, 0x704b, 0x0000, 0x0078, 0x2438, 0x0023, 0x0070, 0x0005,
- 0x0000, 0x0a00, 0x0000, 0x0000, 0x0025, 0x0000, 0x0000, 0x683b,
- 0x0000, 0x6837, 0x0000, 0xa684, 0x0200, 0x0040, 0x4286, 0x78b8,
- 0xa08c, 0x001f, 0xa084, 0x8000, 0x0040, 0x427f, 0x8108, 0x78d8,
- 0xa100, 0x6836, 0x78dc, 0xa081, 0x0000, 0x683a, 0x007c, 0x7990,
- 0x810f, 0xa5ac, 0x0007, 0x2021, 0x0000, 0xa480, 0x0010, 0x789a,
- 0x79a8, 0xa18c, 0x00ff, 0xa184, 0x0080, 0x00c0, 0x42b5, 0xa182,
- 0x0020, 0x00c8, 0x42cf, 0xa182, 0x0012, 0x00c8, 0x4536, 0x2100,
- 0x1079, 0x42a3, 0x007c, 0x4536, 0x447e, 0x4536, 0x4536, 0x42dc,
- 0x42df, 0x4319, 0x434f, 0x4381, 0x4384, 0x4536, 0x4536, 0x433a,
- 0x43a8, 0x43e2, 0x4536, 0x4536, 0x4409, 0xa18c, 0x001f, 0x6814,
- 0xa084, 0x001f, 0xa106, 0x0040, 0x42cc, 0x70b4, 0xa080, 0x00cd,
- 0x781a, 0x2001, 0x0014, 0x1078, 0x454c, 0x1078, 0x45bc, 0x7003,
- 0x0000, 0x2001, 0x0002, 0x007c, 0x2001, 0x0000, 0x007c, 0xa182,
- 0x0024, 0x00c8, 0x4536, 0xa184, 0x0003, 0x1079, 0x42a3, 0x007c,
- 0x4536, 0x4536, 0x4536, 0x4536, 0x1078, 0x4536, 0x007c, 0x2200,
- 0x0079, 0x42e2, 0x440c, 0x440c, 0x4306, 0x4306, 0x4306, 0x4306,
- 0x4306, 0x4306, 0x4306, 0x4306, 0x4304, 0x4306, 0x42fb, 0x4306,
- 0x4306, 0x4306, 0x4306, 0x4306, 0x430e, 0x4311, 0x440c, 0x4311,
- 0x4306, 0x4306, 0x4306, 0x0c7e, 0x077e, 0x6f14, 0x1078, 0x36b0,
- 0x077f, 0x0c7f, 0x0078, 0x4306, 0x1078, 0x44d1, 0x6827, 0x02b3,
- 0x2009, 0x000b, 0x2001, 0x4800, 0x0078, 0x4440, 0x1078, 0x452b,
- 0x007c, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4800, 0x0078,
- 0x4428, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
- 0x4323, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078, 0x45c5, 0x6827,
- 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3a92, 0x1078,
- 0x4466, 0x2b68, 0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x3ac2, 0x2001,
- 0x0002, 0x007c, 0x1078, 0x4466, 0x2001, 0x0017, 0x1078, 0x454c,
- 0x70a3, 0x0000, 0x2009, 0x5038, 0x200b, 0x0006, 0x70af, 0x0017,
- 0x2009, 0x0200, 0x1078, 0x39d2, 0x2001, 0x0001, 0x007c, 0x2200,
- 0x0079, 0x4352, 0x440c, 0x443d, 0x443d, 0x443d, 0x4373, 0x444d,
- 0x4379, 0x444d, 0x444d, 0x4450, 0x4450, 0x4455, 0x4455, 0x436b,
- 0x436b, 0x443d, 0x443d, 0x444d, 0x443d, 0x4379, 0x440c, 0x4379,
- 0x4379, 0x4379, 0x4379, 0x6827, 0x0084, 0x2009, 0x000b, 0x2001,
- 0x4300, 0x0078, 0x445f, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078,
- 0x4440, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078,
- 0x4428, 0x2001, 0x0000, 0x007c, 0x2200, 0x0079, 0x4387, 0x440c,
- 0x43a0, 0x43a0, 0x43a0, 0x43a0, 0x444d, 0x444d, 0x444d, 0x444d,
- 0x444d, 0x444d, 0x444d, 0x444d, 0x43a0, 0x43a0, 0x43a0, 0x43a0,
- 0x444d, 0x43a0, 0x43a0, 0x444d, 0x444d, 0x444d, 0x444d, 0x440c,
- 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078, 0x4428,
- 0xa684, 0x0004, 0x00c0, 0x43bc, 0x6804, 0xa084, 0x00ff, 0xa086,
- 0x0006, 0x00c0, 0x4536, 0x1078, 0x4466, 0x6807, 0x0117, 0x1078,
- 0x3ac2, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084, 0x0004, 0x0040,
- 0x4536, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
- 0x43cb, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078, 0x45c5, 0x6827,
- 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3aa1, 0x1078,
- 0x4466, 0x2b68, 0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x3ac2, 0x2001,
- 0x0002, 0x007c, 0x6000, 0xa084, 0x0004, 0x0040, 0x4536, 0x2d58,
- 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006, 0x00c0, 0x43f1, 0x6807,
- 0x0117, 0x6827, 0x0002, 0x2d58, 0x1078, 0x45c5, 0x6827, 0x0036,
- 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3ab1, 0x1078, 0x4466,
- 0x2b68, 0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x3ac2, 0x2001, 0x0002,
- 0x007c, 0x1078, 0x4536, 0x007c, 0x70b4, 0xa080, 0x00cd, 0x781a,
- 0x2001, 0x0001, 0x1078, 0x454c, 0x1078, 0x45bc, 0x7003, 0x0000,
- 0x2001, 0x0002, 0x007c, 0x1078, 0x457e, 0x1078, 0x45b5, 0x1078,
- 0x426f, 0x1078, 0x4180, 0x1078, 0x45bc, 0x2001, 0x0001, 0x007c,
- 0x1078, 0x457e, 0x1078, 0x45b5, 0x1078, 0x426f, 0x70b4, 0xa080,
- 0x00cd, 0x781a, 0x2001, 0x0013, 0x1078, 0x454c, 0x1078, 0x45bc,
- 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, 0x4536, 0x007c,
- 0x1078, 0x457e, 0x1078, 0x45b5, 0x1078, 0x426f, 0x1078, 0x4180,
- 0x1078, 0x45bc, 0x2001, 0x0001, 0x007c, 0x2001, 0x0003, 0x007c,
- 0x1078, 0x44d1, 0x2001, 0x0000, 0x007c, 0x0c7e, 0x077e, 0x6f14,
- 0x1078, 0x36b0, 0x077f, 0x0c7f, 0x2001, 0x0000, 0x007c, 0x1078,
- 0x457e, 0x1078, 0x4536, 0x2001, 0x0006, 0x007c, 0x6904, 0xa18c,
- 0x00ff, 0xa186, 0x0007, 0x0040, 0x4471, 0xa186, 0x000f, 0x00c0,
- 0x4475, 0x1078, 0x45b5, 0x1078, 0x426f, 0x70b4, 0xa080, 0x00cd,
- 0x781a, 0x1078, 0x45bc, 0x7003, 0x0000, 0x007c, 0x7aa8, 0xa294,
- 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x4536,
- 0x1079, 0x448b, 0x007c, 0x4536, 0x448f, 0x4536, 0x44df, 0xa282,
- 0x0003, 0x0040, 0x4496, 0x1078, 0x4536, 0x007c, 0x7da8, 0xa5ac,
- 0x00ff, 0x7ca8, 0xa4a4, 0x00ff, 0xa482, 0x000c, 0x0048, 0x44a4,
- 0x0040, 0x44a4, 0x2021, 0x000c, 0x701c, 0xa502, 0x00c8, 0x44a9,
- 0x751c, 0x1078, 0x451c, 0x852b, 0x852b, 0x1078, 0x372e, 0x0040,
- 0x44b5, 0x1078, 0x44c3, 0x0078, 0x44b9, 0x1078, 0x4518, 0x1078,
- 0x44d1, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a,
- 0x2001, 0x0004, 0x007c, 0x0c7e, 0x6914, 0x810f, 0xa18c, 0x000f,
- 0x810b, 0x810b, 0x810b, 0xa1e0, 0x5280, 0x1078, 0x3538, 0x0c7f,
- 0x007c, 0x0c7e, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003,
- 0x8003, 0xa0e0, 0x5280, 0x1078, 0x355f, 0x0c7f, 0x007c, 0xa282,
- 0x0002, 0x00c0, 0x4536, 0x7aa8, 0xa294, 0x00ff, 0xa284, 0xfffe,
- 0x0040, 0x44ec, 0x2011, 0x0001, 0x1078, 0x450a, 0x1078, 0x44fc,
- 0x1078, 0x44d1, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9,
- 0x781a, 0x2001, 0x0004, 0x007c, 0x0c7e, 0x6814, 0x8007, 0xa084,
- 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0, 0x5280, 0x1078, 0x3604,
- 0x0c7f, 0x007c, 0x789b, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0002,
- 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0081, 0x78ab, 0x0004, 0x007c,
- 0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0018, 0x78ab, 0x0001,
- 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b, 0x0081,
- 0x78ab, 0x0005, 0x007c, 0x2001, 0x0003, 0x1078, 0x4544, 0x70b4,
- 0xa080, 0x00b9, 0x781a, 0x2001, 0x0005, 0x007c, 0x2001, 0x0007,
- 0x1078, 0x4544, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9,
- 0x781a, 0x2001, 0x0004, 0x007c, 0x789b, 0x0018, 0x78aa, 0x789b,
- 0x0081, 0x78ab, 0x0001, 0x007c, 0x6904, 0xa18c, 0x00ff, 0xa196,
- 0x0007, 0x0040, 0x455a, 0xa196, 0x000f, 0x0040, 0x455a, 0x1078,
- 0x193d, 0x007c, 0x6924, 0xa194, 0x003f, 0x00c0, 0x4563, 0xa18c,
- 0xffc0, 0xa105, 0x6826, 0x1078, 0x3ac2, 0x691c, 0xa184, 0x0100,
- 0x0040, 0x4572, 0x1078, 0x1b7e, 0x6914, 0x1078, 0x3b33, 0x6204,
- 0x8210, 0x6206, 0x007c, 0x692c, 0x6834, 0x682e, 0xa112, 0x6930,
- 0x6838, 0x6832, 0xa11b, 0xa200, 0xa301, 0x007c, 0x0c7e, 0xade0,
- 0x0018, 0x6003, 0x0070, 0x6106, 0x600b, 0x0000, 0x600f, 0x0a00,
- 0x6013, 0x0000, 0x6017, 0x0000, 0x8007, 0x601a, 0x601f, 0x0000,
- 0x6023, 0x0000, 0x0c7f, 0x6824, 0xa085, 0x0080, 0x6826, 0x007c,
- 0x157e, 0x137e, 0x147e, 0x2098, 0xaf80, 0x002d, 0x20a0, 0x81ac,
- 0x0040, 0x45a3, 0x53a6, 0xa184, 0x0001, 0x0040, 0x45a9, 0x3304,
- 0x78be, 0x147f, 0x137f, 0x157f, 0x007c, 0x70b0, 0xa005, 0x10c0,
- 0x23ca, 0x70b3, 0x8000, 0x0078, 0x48f7, 0x71b0, 0x81ff, 0x0040,
- 0x45bb, 0x1078, 0x49ed, 0x007c, 0x71b0, 0x81ff, 0x0040, 0x45c4,
- 0x70b3, 0x0000, 0x1078, 0x4633, 0x007c, 0x0c7e, 0x0d7e, 0x1078,
- 0x191a, 0x0c7f, 0x157e, 0x137e, 0x147e, 0x2da0, 0x2c98, 0x20a9,
- 0x0031, 0x53a3, 0x147f, 0x137f, 0x157f, 0x6807, 0x010d, 0x680b,
- 0x0000, 0x7004, 0x8007, 0x681a, 0x6823, 0x0000, 0x681f, 0x0000,
- 0x689f, 0x0000, 0x0c7f, 0x007c, 0x70b4, 0xa080, 0x0091, 0x781a,
- 0x0078, 0x2438, 0x70b4, 0xa080, 0x0081, 0x781a, 0x0078, 0x2438,
- 0x70b4, 0xa080, 0x00b9, 0x781a, 0x0078, 0x2438, 0x70b4, 0xa080,
- 0x00c3, 0x781a, 0x0078, 0x2438, 0x6904, 0xa18c, 0x00ff, 0xa196,
- 0x0007, 0x0040, 0x4609, 0xa196, 0x000f, 0x0040, 0x4609, 0x6807,
- 0x0117, 0x2001, 0x0200, 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa,
- 0x6820, 0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a,
- 0x71b4, 0xa188, 0x0091, 0x791a, 0x007c, 0x1078, 0x45bc, 0x7848,
- 0xa085, 0x000c, 0x784a, 0x70b4, 0xa080, 0x00cd, 0x781a, 0x2009,
- 0x000b, 0x2001, 0x4400, 0x1078, 0x457e, 0x2001, 0x0013, 0x1078,
- 0x454c, 0x0078, 0x3b60, 0x127e, 0x2091, 0x2200, 0x2049, 0x4633,
- 0x7000, 0x7204, 0xa205, 0x720c, 0xa215, 0x7008, 0xa084, 0xfff7,
- 0xa205, 0x0040, 0x4645, 0x0078, 0x464a, 0x7003, 0x0000, 0x127f,
- 0x2000, 0x007c, 0x7000, 0xa084, 0x0001, 0x00c0, 0x4678, 0x7108,
- 0x8103, 0x00c8, 0x4657, 0x1078, 0x477a, 0x0078, 0x464f, 0x700c,
- 0xa08c, 0x00ff, 0x0040, 0x4678, 0x7004, 0x8004, 0x00c8, 0x466f,
- 0x7014, 0xa005, 0x00c0, 0x466b, 0x7010, 0xa005, 0x0040, 0x466f,
- 0xa102, 0x00c8, 0x464f, 0x7007, 0x0010, 0x0078, 0x4678, 0x8aff,
- 0x0040, 0x4678, 0x1078, 0x49c4, 0x00c0, 0x4672, 0x0040, 0x464f,
- 0x1078, 0x4703, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x017e,
- 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x468b, 0xa18e,
- 0x000f, 0x00c0, 0x468e, 0x6040, 0x0078, 0x468f, 0x6428, 0x017f,
- 0x84ff, 0x0040, 0x46b9, 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8,
- 0x46c9, 0x273c, 0x87fb, 0x00c0, 0x46a7, 0x0048, 0x46a1, 0x1078,
- 0x23ca, 0x609c, 0xa075, 0x0040, 0x46b9, 0x0078, 0x4694, 0x2704,
- 0xae68, 0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0040, 0x46b9,
- 0x8738, 0x2704, 0xa005, 0x00c0, 0x46a8, 0x709c, 0xa075, 0x00c0,
- 0x4694, 0x007c, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011, 0x0015,
- 0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b,
- 0x0000, 0x0000, 0x46be, 0x46bb, 0x0000, 0x0000, 0x8000, 0x0000,
- 0x46be, 0x0000, 0x46c6, 0x46c3, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x46c6, 0x0000, 0x46c1, 0x46c1, 0x0000, 0x0000, 0x8000, 0x0000,
- 0x46c1, 0x0000, 0x46c7, 0x46c7, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x46c7, 0x127e, 0x2091, 0x2200, 0x2079, 0x5000, 0x2071, 0x0010,
- 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2071, 0x0020,
- 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2049, 0x0000,
- 0x127f, 0x2000, 0x007c, 0x2049, 0x4703, 0x2019, 0x0000, 0x7004,
- 0x8004, 0x00c8, 0x4756, 0x7007, 0x0012, 0x7108, 0x7008, 0xa106,
- 0x00c0, 0x470d, 0xa184, 0x01e0, 0x0040, 0x4718, 0x1078, 0x23ca,
- 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x4723, 0xa184,
- 0x4000, 0x00c0, 0x470d, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0040,
- 0x4731, 0xa386, 0x0008, 0x0040, 0x473c, 0xa386, 0x200c, 0x00c0,
- 0x470d, 0x7200, 0x8204, 0x0048, 0x473c, 0x730c, 0xa384, 0x00ff,
- 0x0040, 0x473c, 0x1078, 0x23ca, 0x7007, 0x0012, 0x7000, 0xa084,
- 0x0001, 0x00c0, 0x4756, 0x7008, 0xa084, 0x01e0, 0x00c0, 0x4756,
- 0x7310, 0x7014, 0xa305, 0x0040, 0x4756, 0x710c, 0xa184, 0x0300,
- 0x00c0, 0x4756, 0xa184, 0x00ff, 0x00c0, 0x4703, 0x7007, 0x0012,
- 0x7007, 0x0008, 0x7004, 0xa084, 0x0008, 0x00c0, 0x475a, 0x7007,
- 0x0012, 0x7108, 0x8103, 0x0048, 0x475f, 0x7003, 0x0000, 0x2049,
- 0x0000, 0x007c, 0x107e, 0x007e, 0x127e, 0x157e, 0x2091, 0x2200,
- 0x7108, 0x1078, 0x477a, 0x157f, 0x127f, 0x2091, 0x8001, 0x007f,
- 0x107f, 0x007c, 0x7204, 0x7500, 0x730c, 0xa384, 0x0300, 0x00c0,
- 0x47a1, 0xa184, 0x01e0, 0x00c0, 0x47c5, 0x7108, 0xa184, 0x01e0,
- 0x00c0, 0x47c5, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8,
- 0x4795, 0xa184, 0x4000, 0x00c0, 0x4785, 0xa184, 0x0007, 0x0079,
- 0x4799, 0x47a3, 0x47b5, 0x47a1, 0x47b5, 0x47a1, 0x4801, 0x47a1,
- 0x47ff, 0x1078, 0x23ca, 0x7004, 0xa084, 0x0010, 0xa085, 0x0002,
- 0x7006, 0x8aff, 0x00c0, 0x47b0, 0x2049, 0x0000, 0x0078, 0x47b4,
- 0x1078, 0x49c4, 0x00c0, 0x47b0, 0x007c, 0x7004, 0xa084, 0x0010,
- 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0, 0x47c0, 0x0078, 0x47c4,
- 0x1078, 0x49c4, 0x00c0, 0x47c0, 0x007c, 0x7007, 0x0012, 0x7108,
- 0x00e0, 0x47c8, 0x2091, 0x6000, 0x00e0, 0x47cc, 0x2091, 0x6000,
- 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084, 0x0008, 0x00c0,
- 0x47d4, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048, 0x47d9, 0x7003,
- 0x0000, 0x7000, 0xa005, 0x00c0, 0x47ed, 0x7004, 0xa005, 0x00c0,
- 0x47ed, 0x700c, 0xa005, 0x0040, 0x47ef, 0x0078, 0x47d0, 0x2049,
- 0x0000, 0x1078, 0x37d7, 0x6818, 0xa084, 0x8000, 0x0040, 0x47fa,
- 0x681b, 0x0002, 0x007c, 0x1078, 0x23ca, 0x1078, 0x23ca, 0x1078,
- 0x485d, 0x7210, 0x7114, 0x700c, 0xa09c, 0x00ff, 0x2800, 0xa300,
- 0xa211, 0xa189, 0x0000, 0x1078, 0x485d, 0x2704, 0x2c58, 0xac60,
- 0x6308, 0x2200, 0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305,
- 0x0040, 0x4824, 0x00c8, 0x4824, 0x8412, 0x8210, 0x830a, 0xa189,
- 0x0000, 0x2b60, 0x0078, 0x480b, 0x2b60, 0x8a07, 0x007e, 0x6004,
- 0xa084, 0x0008, 0x0040, 0x4830, 0xa7ba, 0x46c3, 0x0078, 0x4832,
- 0xa7ba, 0x46bb, 0x007f, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92,
- 0x6b8e, 0x7007, 0x0012, 0x1078, 0x4703, 0x007c, 0x8738, 0x2704,
- 0xa005, 0x00c0, 0x4851, 0x609c, 0xa005, 0x0040, 0x485a, 0x2060,
- 0x6004, 0xa084, 0x000f, 0xa080, 0x46c9, 0x203c, 0x87fb, 0x1040,
- 0x23ca, 0x8a51, 0x0040, 0x4859, 0x7008, 0xa084, 0x0003, 0xa086,
- 0x0003, 0x007c, 0x2051, 0x0000, 0x007c, 0x8a50, 0x8739, 0x2704,
- 0xa004, 0x00c0, 0x4871, 0x6000, 0xa064, 0x00c0, 0x4868, 0x2d60,
- 0x6004, 0xa084, 0x000f, 0xa080, 0x46d9, 0x203c, 0x87fb, 0x1040,
- 0x23ca, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x6884,
- 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084,
- 0x00ff, 0x007e, 0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x488c,
- 0xa0b8, 0x46c3, 0x0078, 0x488e, 0xa0b8, 0x46bb, 0x7e08, 0xa6b5,
- 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x489c,
- 0xa18e, 0x000f, 0x00c0, 0x48a5, 0x681c, 0xa084, 0x0040, 0x0040,
- 0x48ac, 0xa6b5, 0x0001, 0x0078, 0x48ac, 0x681c, 0xa084, 0x0040,
- 0x0040, 0x48ac, 0xa6b5, 0x0001, 0x7007, 0x0004, 0x7004, 0xa084,
- 0x0004, 0x00c0, 0x48ae, 0x2400, 0xa305, 0x00c0, 0x48b9, 0x0078,
- 0x48df, 0x2c58, 0x2704, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a,
- 0x6004, 0xa301, 0x701e, 0xa184, 0x0008, 0x0040, 0x48cf, 0x6010,
- 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208,
- 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, 0xa203, 0x7016, 0x7602,
- 0x7007, 0x0001, 0x2b60, 0x1078, 0x483e, 0x0078, 0x48e1, 0x1078,
- 0x49c4, 0x00c0, 0x48df, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e,
- 0x2091, 0x2200, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004,
- 0x00c0, 0x48ed, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e,
- 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049, 0x48f7, 0x7007, 0x0004,
- 0x7004, 0xa084, 0x0004, 0x00c0, 0x4900, 0x7e08, 0xa6b5, 0x000c,
- 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4913, 0xa18e,
- 0x000f, 0x00c0, 0x491e, 0x681c, 0xa084, 0x0040, 0x0040, 0x491a,
- 0xa6b5, 0x0001, 0x6840, 0x2050, 0x0078, 0x4927, 0x681c, 0xa084,
- 0x0020, 0x00c0, 0x4925, 0xa6b5, 0x0001, 0x6828, 0x2050, 0x2d60,
- 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x46c9, 0x273c, 0x87fb, 0x00c0,
- 0x493b, 0x0048, 0x4935, 0x1078, 0x23ca, 0x689c, 0xa065, 0x0040,
- 0x493f, 0x0078, 0x4928, 0x1078, 0x49c4, 0x00c0, 0x493b, 0x127f,
- 0x2000, 0x007c, 0x127e, 0x007e, 0x017e, 0x0d7e, 0x2091, 0x2200,
- 0x0d7f, 0x037f, 0x047f, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c,
- 0x00ff, 0xa186, 0x0007, 0x0040, 0x4959, 0xa18e, 0x000f, 0x00c0,
- 0x4962, 0x681c, 0xa084, 0x0040, 0x0040, 0x4969, 0xa6b5, 0x0001,
- 0x0078, 0x4969, 0x681c, 0xa084, 0x0040, 0x0040, 0x4969, 0xa6b5,
- 0x0001, 0x2049, 0x4942, 0x017e, 0x6904, 0xa18c, 0x00ff, 0xa186,
- 0x0007, 0x0040, 0x4977, 0xa18e, 0x000f, 0x00c0, 0x497a, 0x6840,
- 0x0078, 0x497b, 0x6828, 0x017f, 0xa055, 0x0040, 0x49c1, 0x2d70,
- 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x46c9, 0x273c, 0x87fb,
- 0x00c0, 0x4995, 0x0048, 0x498e, 0x1078, 0x23ca, 0x709c, 0xa075,
- 0x2060, 0x0040, 0x49c1, 0x0078, 0x4981, 0x2704, 0xae68, 0x6808,
- 0xa422, 0x680c, 0xa31b, 0x0048, 0x49ae, 0x8a51, 0x00c0, 0x49a2,
- 0x1078, 0x23ca, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4996, 0x709c,
- 0xa075, 0x2060, 0x0040, 0x49c1, 0x0078, 0x4981, 0x8422, 0x8420,
- 0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300,
- 0xa11b, 0x00c8, 0x49bd, 0x1078, 0x23ca, 0x2071, 0x0020, 0x0078,
- 0x48ac, 0x127f, 0x2000, 0x007c, 0x7008, 0xa084, 0x0003, 0xa086,
- 0x0003, 0x0040, 0x49ec, 0x2704, 0xac08, 0x2104, 0x701a, 0x8108,
- 0x2104, 0x701e, 0x8108, 0x2104, 0x7012, 0x8108, 0x2104, 0x7016,
- 0x6004, 0xa084, 0x0008, 0x0040, 0x49e3, 0x8108, 0x2104, 0x7022,
- 0x8108, 0x2104, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xa085,
- 0x0001, 0x7006, 0x1078, 0x483e, 0x007c, 0x127e, 0x007e, 0x0d7e,
- 0x2091, 0x2200, 0x2049, 0x49ed, 0x0d7f, 0x087f, 0x7108, 0xa184,
- 0x0003, 0x00c0, 0x4a17, 0x017e, 0x6904, 0xa18c, 0x00ff, 0xa186,
- 0x0007, 0x0040, 0x4a07, 0xa18e, 0x000f, 0x00c0, 0x4a0a, 0x6840,
- 0x0078, 0x4a0b, 0x6828, 0x017f, 0xa005, 0x0040, 0x4a25, 0x0078,
- 0x464a, 0x0020, 0x4a17, 0x1078, 0x4801, 0x0078, 0x4a25, 0x00a0,
- 0x4a1e, 0x7108, 0x1078, 0x477a, 0x0078, 0x49f6, 0x7007, 0x0010,
- 0x00a0, 0x4a20, 0x7108, 0x1078, 0x477a, 0x7008, 0xa086, 0x0008,
- 0x00c0, 0x49f6, 0x7000, 0xa005, 0x00c0, 0x49f6, 0x7003, 0x0000,
- 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, 0x127e, 0x147e, 0x137e,
- 0x157e, 0x0c7e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049, 0x4a35,
- 0xad80, 0x0011, 0x20a0, 0x2099, 0x0031, 0x700c, 0xa084, 0x00ff,
- 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0040,
- 0x4a54, 0x8000, 0x80ac, 0x53a5, 0x7007, 0x0004, 0x7004, 0xa084,
- 0x0004, 0x00c0, 0x4a56, 0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000,
- 0x157f, 0x137f, 0x147f, 0x127f, 0x2000, 0x007c, 0x2091, 0x6000,
- 0x2091, 0x8000, 0x78cc, 0xa005, 0x0040, 0x4a7d, 0x7994, 0x70d0,
- 0xa106, 0x00c0, 0x4a7d, 0x7804, 0xa005, 0x0040, 0x4a7d, 0x7807,
- 0x0000, 0x0068, 0x4a7d, 0x2091, 0x4080, 0x7820, 0x8001, 0x7822,
- 0x00c0, 0x4ad8, 0x7824, 0x7822, 0x2069, 0x5040, 0x6800, 0xa084,
- 0x0007, 0x0040, 0x4a9b, 0xa086, 0x0002, 0x0040, 0x4a9b, 0x6834,
- 0xa00d, 0x0040, 0x4a9b, 0x2104, 0xa005, 0x0040, 0x4a9b, 0x8001,
- 0x200a, 0x0040, 0x4b80, 0x7848, 0xa005, 0x0040, 0x4aa9, 0x8001,
- 0x784a, 0x00c0, 0x4aa9, 0x2009, 0x0102, 0x6844, 0x200a, 0x1078,
- 0x21b1, 0x6890, 0xa005, 0x0040, 0x4ab5, 0x8001, 0x6892, 0x00c0,
- 0x4ab5, 0x686f, 0x0000, 0x6873, 0x0001, 0x2061, 0x5300, 0x20a9,
- 0x0100, 0x2009, 0x0002, 0x6034, 0xa005, 0x0040, 0x4acb, 0x8001,
- 0x6036, 0x00c0, 0x4acb, 0x6010, 0xa005, 0x0040, 0x4acb, 0x017e,
- 0x1078, 0x21b1, 0x017f, 0xace0, 0x0010, 0x0070, 0x4ad1, 0x0078,
- 0x4abb, 0x8109, 0x0040, 0x4ad8, 0x20a9, 0x0100, 0x0078, 0x4abb,
- 0x1078, 0x4ae5, 0x1078, 0x4b0a, 0x2009, 0x5051, 0x2104, 0x2009,
- 0x0102, 0x200a, 0x2091, 0x8001, 0x007c, 0x7834, 0x8001, 0x7836,
- 0x00c0, 0x4b09, 0x7838, 0x7836, 0x2091, 0x8000, 0x7844, 0xa005,
- 0x00c0, 0x4af4, 0x2001, 0x0101, 0x8001, 0x7846, 0xa080, 0x7300,
- 0x2040, 0x2004, 0xa065, 0x0040, 0x4b09, 0x6024, 0xa005, 0x0040,
- 0x4b05, 0x8001, 0x6026, 0x0040, 0x4b39, 0x6000, 0x2c40, 0x0078,
- 0x4afa, 0x007c, 0x7828, 0x8001, 0x782a, 0x00c0, 0x4b38, 0x782c,
- 0x782a, 0x7830, 0xa005, 0x00c0, 0x4b17, 0x2001, 0x0200, 0x8001,
- 0x7832, 0x8003, 0x8003, 0x8003, 0x8003, 0xa090, 0x5300, 0xa298,
- 0x0002, 0x2304, 0xa084, 0x0008, 0x0040, 0x4b38, 0xa290, 0x0009,
- 0x2204, 0xa005, 0x0040, 0x4b30, 0x8001, 0x2012, 0x00c0, 0x4b38,
- 0x2304, 0xa084, 0xfff7, 0xa085, 0x0080, 0x201a, 0x1078, 0x21b1,
- 0x007c, 0x2069, 0x5040, 0x6800, 0xa005, 0x0040, 0x4b43, 0x6848,
- 0xac06, 0x0040, 0x4b80, 0x601b, 0x0006, 0x60b4, 0xa084, 0x3f00,
- 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022, 0x6000,
- 0x2042, 0x6714, 0x6f82, 0x1078, 0x1956, 0x6818, 0xa005, 0x0040,
- 0x4b5b, 0x8001, 0x681a, 0x6808, 0xa084, 0xffef, 0x680a, 0x6810,
- 0x8001, 0x00d0, 0x4b65, 0x1078, 0x23ca, 0x6812, 0x602f, 0x0000,
- 0x6033, 0x0000, 0x2c68, 0x1078, 0x1c53, 0x2069, 0x5040, 0x7944,
- 0xa184, 0x0100, 0x2001, 0x0006, 0x686e, 0x00c0, 0x4b7b, 0x6986,
- 0x2001, 0x0004, 0x686e, 0x1078, 0x21ac, 0x2091, 0x8001, 0x007c,
- 0x2069, 0x0100, 0x2009, 0x5040, 0x2104, 0xa084, 0x0007, 0x0040,
- 0x4bdc, 0xa086, 0x0007, 0x00c0, 0x4b96, 0x0d7e, 0x2009, 0x5052,
- 0x216c, 0x1078, 0x3a1a, 0x0d7f, 0x0078, 0x4bdc, 0x2009, 0x5052,
- 0x2164, 0x1078, 0x2375, 0x601b, 0x0006, 0x6858, 0xa084, 0x3f00,
- 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f,
- 0x0000, 0x6033, 0x0000, 0x6830, 0xa084, 0x0040, 0x0040, 0x4bd0,
- 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004, 0x0040,
- 0x4bbd, 0x0070, 0x4bbd, 0x0078, 0x4bb4, 0x684b, 0x0009, 0x20a9,
- 0x0014, 0x6848, 0xa084, 0x0001, 0x0040, 0x4bca, 0x0070, 0x4bca,
- 0x0078, 0x4bc1, 0x20a9, 0x00fa, 0x0070, 0x4bd0, 0x0078, 0x4bcc,
- 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2009, 0x505b,
- 0x200b, 0x0007, 0x784c, 0x784a, 0x2091, 0x8001, 0x007c, 0x2079,
- 0x5000, 0x1078, 0x4c0a, 0x1078, 0x4bee, 0x1078, 0x4bfc, 0x7833,
- 0x0000, 0x7847, 0x0000, 0x784b, 0x0000, 0x007c, 0x2019, 0x0003,
- 0x2011, 0x5046, 0x2204, 0xa086, 0x003c, 0x0040, 0x4bf9, 0x2019,
- 0x0002, 0x7b2a, 0x7b2e, 0x007c, 0x2019, 0x0039, 0x2011, 0x5046,
- 0x2204, 0xa086, 0x003c, 0x0040, 0x4c07, 0x2019, 0x0027, 0x7b36,
- 0x7b3a, 0x007c, 0x2019, 0x3971, 0x2011, 0x5046, 0x2204, 0xa086,
- 0x003c, 0x0040, 0x4c15, 0x2019, 0x2626, 0x7b22, 0x7b26, 0x783f,
- 0x0000, 0x7843, 0x000a, 0x007c, 0x0020, 0x002b, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0014,
- 0x0014, 0x9849, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014,
- 0x0014, 0x0080, 0x000f, 0x0000, 0x0201, 0x0604, 0x0c08, 0x2120,
- 0x4022, 0xf880, 0x0018, 0x300b, 0xa201, 0x0014, 0xa200, 0x0014,
- 0xa200, 0x0214, 0x0000, 0x006c, 0x0002, 0x0014, 0x98d5, 0x009e,
- 0x009b, 0xa202, 0x8838, 0x3806, 0x8839, 0x20c3, 0x0864, 0x9889,
- 0x28c1, 0x9cb6, 0xa203, 0x300c, 0x2846, 0x8161, 0x846a, 0x8300,
- 0x1856, 0x883a, 0x9865, 0x28f2, 0x9c95, 0x9858, 0x300c, 0x28e1,
- 0x9c95, 0x2809, 0xa206, 0x64c0, 0x67a0, 0x6fc0, 0x1814, 0x883b,
- 0x782c, 0x786d, 0x9879, 0x282b, 0xa207, 0x64a0, 0x67a0, 0x6fc0,
- 0x1814, 0x883b, 0x7822, 0x883e, 0x987d, 0x8576, 0x8677, 0x206b,
- 0x28c1, 0x9cb6, 0x2044, 0x2103, 0x20a2, 0x2081, 0x9865, 0xa209,
- 0x2901, 0x9891, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c,
- 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c95, 0x0014, 0xa204,
- 0xa300, 0x3009, 0x19e2, 0xf868, 0x8176, 0x86eb, 0x85eb, 0x872e,
- 0x87a9, 0x883f, 0x08e6, 0x9895, 0xf881, 0x9890, 0xc801, 0x0014,
- 0xf8c1, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014,
- 0x8532, 0xf241, 0x0014, 0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014,
- 0xa208, 0x6043, 0x8008, 0x1dc1, 0x0016, 0x8300, 0x8160, 0x842a,
- 0xf041, 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d5,
- 0x8822, 0x0016, 0x8000, 0x2847, 0x1011, 0x98c8, 0x8000, 0xa000,
- 0x2802, 0x1011, 0x98ce, 0x9865, 0x283e, 0x1011, 0x98d2, 0xa20b,
- 0x0017, 0x300c, 0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210, 0x98df,
- 0x0014, 0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d,
- 0x3806, 0x0210, 0x9cbb, 0x0704, 0x0000, 0x006c, 0x0002, 0x984f,
- 0x0014, 0x009e, 0x00a0, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211,
- 0x9cd0, 0x8772, 0x8837, 0x2101, 0x987a, 0x10d2, 0x78e2, 0x9cd3,
- 0x9859, 0xd984, 0xf0e2, 0xf0a1, 0x98cd, 0x0014, 0x8831, 0xd166,
- 0x8830, 0x800f, 0x9401, 0xb520, 0xc802, 0x8820, 0x987a, 0x2301,
- 0x987a, 0x10d2, 0x78e4, 0x9cd3, 0x8821, 0x8820, 0x9859, 0xf123,
- 0xf142, 0xf101, 0x98c6, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c,
- 0xd99e, 0x6001, 0x0014, 0x6845, 0x0214, 0xa21b, 0x9cd0, 0x2001,
- 0x98c5, 0x8201, 0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0x988d,
- 0x3027, 0x84a8, 0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9cbc,
- 0x6b2a, 0x6902, 0x1834, 0x989d, 0x1814, 0x8010, 0x8592, 0x8026,
- 0x84b9, 0x7021, 0x0014, 0xa300, 0x69e1, 0x9ca9, 0x694b, 0xa213,
- 0x1462, 0xa213, 0x8000, 0x16e1, 0x98b5, 0x8023, 0x16e1, 0x8001,
- 0x10f1, 0x0016, 0x6969, 0xa214, 0x61c2, 0x8002, 0x14e1, 0x8004,
- 0x16e1, 0x0101, 0x300a, 0x8827, 0x0014, 0xa217, 0x9cbc, 0x0014,
- 0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6, 0x882c, 0x0016, 0xa212,
- 0x9cd0, 0x10d2, 0x70e4, 0x0004, 0x8007, 0x9424, 0xcc1a, 0x9cd3,
- 0x98c5, 0x8827, 0x300a, 0x0013, 0x8000, 0x84a4, 0x0016, 0x11c2,
- 0x211e, 0x870e, 0xa21d, 0x0014, 0x878e, 0x0016, 0xa21c, 0x1035,
- 0x9891, 0xa210, 0xa000, 0x8010, 0x8592, 0x853b, 0xd044, 0x8022,
- 0x3807, 0x84bb, 0x98ea, 0x8021, 0x3807, 0x84b9, 0x300c, 0x817e,
- 0x872b, 0x8772, 0x9891, 0x0000, 0x0020, 0x002b, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0014,
- 0x0014, 0x9849, 0x0014, 0x0014, 0x98ea, 0x98d5, 0x0014, 0x0014,
- 0x0014, 0x0080, 0x013f, 0x0000, 0x0201, 0x0604, 0x0c08, 0x2120,
- 0x4022, 0xf880, 0x0018, 0x300b, 0xa201, 0x0014, 0xa200, 0x0014,
- 0xa200, 0x0214, 0xa202, 0x8838, 0x3806, 0x8839, 0x20c3, 0x0864,
- 0xa833, 0x28c1, 0x9cb6, 0xa203, 0x300c, 0x2846, 0x8161, 0x846a,
- 0x8300, 0x1856, 0x883a, 0xa804, 0x28f2, 0x9c95, 0xa8f4, 0x300c,
- 0x28e1, 0x9c95, 0x2809, 0xa206, 0x64c0, 0x67a0, 0x6fc0, 0x1814,
- 0x883b, 0x782c, 0x786d, 0xa808, 0x282b, 0xa207, 0x64a0, 0x67a0,
- 0x6fc0, 0x1814, 0x883b, 0x7822, 0x883e, 0xa802, 0x8576, 0x8677,
- 0x206b, 0x28c1, 0x9cb6, 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8e0,
- 0xa209, 0x2901, 0xa809, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a,
- 0x883c, 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c95, 0x0014,
- 0xa204, 0xa300, 0x3009, 0x19e2, 0xf868, 0x8176, 0x86eb, 0x85eb,
- 0x872e, 0x87a9, 0x883f, 0x08e6, 0xa8f3, 0xf881, 0xa8ec, 0xc801,
- 0x0014, 0xf8c1, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfb02, 0x1de2,
- 0x0014, 0x8532, 0xf241, 0x0014, 0x1de2, 0x84a8, 0xd7a0, 0x1fe6,
- 0x0014, 0xa208, 0x6043, 0x8008, 0x1dc1, 0x0016, 0x8300, 0x8160,
- 0x842a, 0xf041, 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011,
- 0x20d5, 0x8822, 0x0016, 0x8000, 0x2847, 0x1011, 0xa8fc, 0x8000,
- 0xa000, 0x2802, 0x1011, 0xa8fd, 0xa893, 0x283e, 0x1011, 0xa8fd,
- 0xa20b, 0x0017, 0x300c, 0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210,
- 0xa801, 0x0014, 0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014,
- 0xa20d, 0x3806, 0x0210, 0x9cbb, 0x0704, 0x0017, 0x60ff, 0x300c,
- 0x8720, 0xa211, 0x9d6b, 0x8772, 0x8837, 0x2101, 0xa821, 0x10d2,
- 0x78e2, 0x9d6e, 0xa8fc, 0xd984, 0xf0e2, 0xf0a1, 0xa86c, 0x0014,
- 0x8831, 0xd166, 0x8830, 0x800f, 0x9401, 0xb520, 0xc802, 0x8820,
- 0xa80f, 0x2301, 0xa80d, 0x10d2, 0x78e4, 0x9d6e, 0x8821, 0x8820,
- 0xa8e6, 0xf123, 0xf142, 0xf101, 0xa84f, 0x10d2, 0x70f6, 0x8832,
- 0x8203, 0x870c, 0xd99e, 0x6001, 0x0014, 0x6845, 0x0214, 0xa21b,
- 0x9d6b, 0x2001, 0xa840, 0x8201, 0x1852, 0xd184, 0xd163, 0x8834,
- 0x8001, 0xa801, 0x3027, 0x84a8, 0x1a56, 0x8833, 0x0014, 0xa218,
- 0x6981, 0x9d57, 0x6b2a, 0x6902, 0x1834, 0xa805, 0x1814, 0x8010,
- 0x8592, 0x8026, 0x84b9, 0x7021, 0x0014, 0xa300, 0x69e1, 0x9d44,
- 0x694b, 0xa213, 0x1462, 0xa213, 0x8000, 0x16e1, 0xa80c, 0x8023,
- 0x16e1, 0x8001, 0x10f1, 0x0016, 0x6969, 0xa214, 0x61c2, 0x8002,
- 0x14e1, 0x8004, 0x16e1, 0x0101, 0x300a, 0x8827, 0x0014, 0xa217,
- 0x9d57, 0x0014, 0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6, 0x882c,
- 0x0016, 0xa212, 0x9d6b, 0x10d2, 0x70e4, 0x0004, 0x8007, 0x9424,
- 0xcc1a, 0x9d6e, 0xa8f8, 0x8827, 0x300a, 0x0013, 0x8000, 0x84a4,
- 0x0016, 0x11c2, 0x211e, 0x870e, 0xa21d, 0x0014, 0x878e, 0x0016,
- 0xa21c, 0x1035, 0xa8b4, 0xa210, 0x3807, 0x300c, 0x817e, 0x872b,
- 0x8772, 0xa8ad, 0x0000, 0x8ec6
-};
-
-#endif /* RELOAD_FIRMWARE */
-
-static const unsigned short risc_code_length01 = 0x3f14;
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c
index caa0c36..5b1c120 100644
--- a/drivers/scsi/raid_class.c
+++ b/drivers/scsi/raid_class.c
@@ -1,5 +1,13 @@
/*
- * RAID Attributes
+ * raid_class.c - implementation of a simple raid visualisation class
+ *
+ * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com>
+ *
+ * This file is licensed under GPLv2
+ *
+ * This class is designed to allow raid attributes to be visualised and
+ * manipulated in a form independent of the underlying raid. Ultimately this
+ * should work for both hardware and software raids.
*/
#include <linux/init.h>
#include <linux/module.h>
@@ -24,7 +32,7 @@ struct raid_internal {
struct raid_component {
struct list_head node;
- struct device *dev;
+ struct class_device cdev;
int num;
};
@@ -74,11 +82,10 @@ static int raid_setup(struct transport_container *tc, struct device *dev,
BUG_ON(class_get_devdata(cdev));
- rd = kmalloc(sizeof(*rd), GFP_KERNEL);
+ rd = kzalloc(sizeof(*rd), GFP_KERNEL);
if (!rd)
return -ENOMEM;
- memset(rd, 0, sizeof(*rd));
INIT_LIST_HEAD(&rd->component_list);
class_set_devdata(cdev, rd);
@@ -90,15 +97,15 @@ static int raid_remove(struct transport_container *tc, struct device *dev,
{
struct raid_data *rd = class_get_devdata(cdev);
struct raid_component *rc, *next;
+ dev_printk(KERN_ERR, dev, "RAID REMOVE\n");
class_set_devdata(cdev, NULL);
list_for_each_entry_safe(rc, next, &rd->component_list, node) {
- char buf[40];
- snprintf(buf, sizeof(buf), "component-%d", rc->num);
list_del(&rc->node);
- sysfs_remove_link(&cdev->kobj, buf);
- kfree(rc);
+ dev_printk(KERN_ERR, rc->cdev.dev, "RAID COMPONENT REMOVE\n");
+ class_device_unregister(&rc->cdev);
}
- kfree(class_get_devdata(cdev));
+ dev_printk(KERN_ERR, dev, "RAID REMOVE DONE\n");
+ kfree(rd);
return 0;
}
@@ -112,10 +119,11 @@ static struct {
enum raid_state value;
char *name;
} raid_states[] = {
- { RAID_ACTIVE, "active" },
- { RAID_DEGRADED, "degraded" },
- { RAID_RESYNCING, "resyncing" },
- { RAID_OFFLINE, "offline" },
+ { RAID_STATE_UNKNOWN, "unknown" },
+ { RAID_STATE_ACTIVE, "active" },
+ { RAID_STATE_DEGRADED, "degraded" },
+ { RAID_STATE_RESYNCING, "resyncing" },
+ { RAID_STATE_OFFLINE, "offline" },
};
static const char *raid_state_name(enum raid_state state)
@@ -132,6 +140,33 @@ static const char *raid_state_name(enum raid_state state)
return name;
}
+static struct {
+ enum raid_level value;
+ char *name;
+} raid_levels[] = {
+ { RAID_LEVEL_UNKNOWN, "unknown" },
+ { RAID_LEVEL_LINEAR, "linear" },
+ { RAID_LEVEL_0, "raid0" },
+ { RAID_LEVEL_1, "raid1" },
+ { RAID_LEVEL_3, "raid3" },
+ { RAID_LEVEL_4, "raid4" },
+ { RAID_LEVEL_5, "raid5" },
+ { RAID_LEVEL_6, "raid6" },
+};
+
+static const char *raid_level_name(enum raid_level level)
+{
+ int i;
+ char *name = NULL;
+
+ for (i = 0; i < sizeof(raid_levels)/sizeof(raid_levels[0]); i++) {
+ if (raid_levels[i].value == level) {
+ name = raid_levels[i].name;
+ break;
+ }
+ }
+ return name;
+}
#define raid_attr_show_internal(attr, fmt, var, code) \
static ssize_t raid_show_##attr(struct class_device *cdev, char *buf) \
@@ -161,11 +196,22 @@ static CLASS_DEVICE_ATTR(attr, S_IRUGO, raid_show_##attr, NULL)
#define raid_attr_ro(attr) raid_attr_ro_internal(attr, )
#define raid_attr_ro_fn(attr) raid_attr_ro_internal(attr, ATTR_CODE(attr))
-#define raid_attr_ro_state(attr) raid_attr_ro_states(attr, attr, ATTR_CODE(attr))
+#define raid_attr_ro_state(attr) raid_attr_ro_states(attr, attr, )
+#define raid_attr_ro_state_fn(attr) raid_attr_ro_states(attr, attr, ATTR_CODE(attr))
+
-raid_attr_ro(level);
+raid_attr_ro_state(level);
raid_attr_ro_fn(resync);
-raid_attr_ro_state(state);
+raid_attr_ro_state_fn(state);
+
+static void raid_component_release(struct class_device *cdev)
+{
+ struct raid_component *rc = container_of(cdev, struct raid_component,
+ cdev);
+ dev_printk(KERN_ERR, rc->cdev.dev, "COMPONENT RELEASE\n");
+ put_device(rc->cdev.dev);
+ kfree(rc);
+}
void raid_component_add(struct raid_template *r,struct device *raid_dev,
struct device *component_dev)
@@ -175,34 +221,36 @@ void raid_component_add(struct raid_template *r,struct device *raid_dev,
raid_dev);
struct raid_component *rc;
struct raid_data *rd = class_get_devdata(cdev);
- char buf[40];
- rc = kmalloc(sizeof(*rc), GFP_KERNEL);
+ rc = kzalloc(sizeof(*rc), GFP_KERNEL);
if (!rc)
return;
INIT_LIST_HEAD(&rc->node);
- rc->dev = component_dev;
+ class_device_initialize(&rc->cdev);
+ rc->cdev.release = raid_component_release;
+ rc->cdev.dev = get_device(component_dev);
rc->num = rd->component_count++;
- snprintf(buf, sizeof(buf), "component-%d", rc->num);
+ snprintf(rc->cdev.class_id, sizeof(rc->cdev.class_id),
+ "component-%d", rc->num);
list_add_tail(&rc->node, &rd->component_list);
- sysfs_create_link(&cdev->kobj, &component_dev->kobj, buf);
+ rc->cdev.parent = cdev;
+ rc->cdev.class = &raid_class.class;
+ class_device_add(&rc->cdev);
}
EXPORT_SYMBOL(raid_component_add);
struct raid_template *
raid_class_attach(struct raid_function_template *ft)
{
- struct raid_internal *i = kmalloc(sizeof(struct raid_internal),
+ struct raid_internal *i = kzalloc(sizeof(struct raid_internal),
GFP_KERNEL);
int count = 0;
if (unlikely(!i))
return NULL;
- memset(i, 0, sizeof(*i));
-
i->f = ft;
i->r.raid_attrs.ac.class = &raid_class.class;
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 93d5523..ab7432a 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -1,7 +1,8 @@
/*
* sata_mv.c - Marvell SATA support
*
- * Copyright 2005: EMC Corporation, all rights reserved.
+ * Copyright 2005: EMC Corporation, all rights reserved.
+ * Copyright 2005 Red Hat, Inc. All rights reserved.
*
* Please ALWAYS copy linux-ide@vger.kernel.org on emails.
*
@@ -36,7 +37,7 @@
#include <asm/io.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "0.25"
+#define DRV_VERSION "0.5"
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -50,6 +51,9 @@ enum {
MV_PCI_REG_BASE = 0,
MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */
MV_SATAHC0_REG_BASE = 0x20000,
+ MV_FLASH_CTL = 0x1046c,
+ MV_GPIO_PORT_CTL = 0x104f0,
+ MV_RESET_CFG = 0x180d8,
MV_PCI_REG_SZ = MV_MAJOR_REG_AREA_SZ,
MV_SATAHC_REG_SZ = MV_MAJOR_REG_AREA_SZ,
@@ -72,11 +76,6 @@ enum {
MV_SG_TBL_SZ = (16 * MV_MAX_SG_CT),
MV_PORT_PRIV_DMA_SZ = (MV_CRQB_Q_SZ + MV_CRPB_Q_SZ + MV_SG_TBL_SZ),
- /* Our DMA boundary is determined by an ePRD being unable to handle
- * anything larger than 64KB
- */
- MV_DMA_BOUNDARY = 0xffffU,
-
MV_PORTS_PER_HC = 4,
/* == (port / MV_PORTS_PER_HC) to determine HC from 0-7 port */
MV_PORT_HC_SHIFT = 2,
@@ -86,16 +85,9 @@ enum {
/* Host Flags */
MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */
MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */
- MV_FLAG_GLBL_SFT_RST = (1 << 28), /* Global Soft Reset support */
MV_COMMON_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO),
- MV_6XXX_FLAGS = (MV_FLAG_IRQ_COALESCE |
- MV_FLAG_GLBL_SFT_RST),
-
- chip_504x = 0,
- chip_508x = 1,
- chip_604x = 2,
- chip_608x = 3,
+ MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE,
CRQB_FLAG_READ = (1 << 0),
CRQB_TAG_SHIFT = 1,
@@ -116,8 +108,19 @@ enum {
PCI_MASTER_EMPTY = (1 << 3),
GLOB_SFT_RST = (1 << 4),
- PCI_IRQ_CAUSE_OFS = 0x1d58,
- PCI_IRQ_MASK_OFS = 0x1d5c,
+ MV_PCI_MODE = 0xd00,
+ MV_PCI_EXP_ROM_BAR_CTL = 0xd2c,
+ MV_PCI_DISC_TIMER = 0xd04,
+ MV_PCI_MSI_TRIGGER = 0xc38,
+ MV_PCI_SERR_MASK = 0xc28,
+ MV_PCI_XBAR_TMOUT = 0x1d04,
+ MV_PCI_ERR_LOW_ADDRESS = 0x1d40,
+ MV_PCI_ERR_HIGH_ADDRESS = 0x1d44,
+ MV_PCI_ERR_ATTRIBUTE = 0x1d48,
+ MV_PCI_ERR_COMMAND = 0x1d50,
+
+ PCI_IRQ_CAUSE_OFS = 0x1d58,
+ PCI_IRQ_MASK_OFS = 0x1d5c,
PCI_UNMASK_ALL_IRQS = 0x7fffff, /* bits 22-0 */
HC_MAIN_IRQ_CAUSE_OFS = 0x1d60,
@@ -134,7 +137,7 @@ enum {
SELF_INT = (1 << 23),
TWSI_INT = (1 << 24),
HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */
- HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE |
+ HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE |
PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT |
HC_MAIN_RSVD),
@@ -153,6 +156,15 @@ enum {
/* SATA registers */
SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */
SATA_ACTIVE_OFS = 0x350,
+ PHY_MODE3 = 0x310,
+ PHY_MODE4 = 0x314,
+ PHY_MODE2 = 0x330,
+ MV5_PHY_MODE = 0x74,
+ MV5_LT_MODE = 0x30,
+ MV5_PHY_CTL = 0x0C,
+ SATA_INTERFACE_CTL = 0x050,
+
+ MV_M2_PREAMP_MASK = 0x7e0,
/* Port registers */
EDMA_CFG_OFS = 0,
@@ -182,17 +194,16 @@ enum {
EDMA_ERR_LNK_CTRL_TX = (0x1f << 21),
EDMA_ERR_LNK_DATA_TX = (0x1f << 26),
EDMA_ERR_TRANS_PROTO = (1 << 31),
- EDMA_ERR_FATAL = (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR |
+ EDMA_ERR_FATAL = (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR |
EDMA_ERR_DEV_DCON | EDMA_ERR_CRBQ_PAR |
EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR |
- EDMA_ERR_IORDY | EDMA_ERR_LNK_CTRL_RX_2 |
+ EDMA_ERR_IORDY | EDMA_ERR_LNK_CTRL_RX_2 |
EDMA_ERR_LNK_DATA_RX |
- EDMA_ERR_LNK_DATA_TX |
+ EDMA_ERR_LNK_DATA_TX |
EDMA_ERR_TRANS_PROTO),
EDMA_REQ_Q_BASE_HI_OFS = 0x10,
EDMA_REQ_Q_IN_PTR_OFS = 0x14, /* also contains BASE_LO */
- EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U,
EDMA_REQ_Q_OUT_PTR_OFS = 0x18,
EDMA_REQ_Q_PTR_SHIFT = 5,
@@ -200,7 +211,6 @@ enum {
EDMA_RSP_Q_BASE_HI_OFS = 0x1c,
EDMA_RSP_Q_IN_PTR_OFS = 0x20,
EDMA_RSP_Q_OUT_PTR_OFS = 0x24, /* also contains BASE_LO */
- EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U,
EDMA_RSP_Q_PTR_SHIFT = 3,
EDMA_CMD_OFS = 0x28,
@@ -208,14 +218,44 @@ enum {
EDMA_DS = (1 << 1),
ATA_RST = (1 << 2),
+ EDMA_IORDY_TMOUT = 0x34,
+ EDMA_ARB_CFG = 0x38,
+
/* Host private flags (hp_flags) */
MV_HP_FLAG_MSI = (1 << 0),
+ MV_HP_ERRATA_50XXB0 = (1 << 1),
+ MV_HP_ERRATA_50XXB2 = (1 << 2),
+ MV_HP_ERRATA_60X1B2 = (1 << 3),
+ MV_HP_ERRATA_60X1C0 = (1 << 4),
+ MV_HP_50XX = (1 << 5),
/* Port private flags (pp_flags) */
MV_PP_FLAG_EDMA_EN = (1 << 0),
MV_PP_FLAG_EDMA_DS_ACT = (1 << 1),
};
+#define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX)
+#define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0)
+
+enum {
+ /* Our DMA boundary is determined by an ePRD being unable to handle
+ * anything larger than 64KB
+ */
+ MV_DMA_BOUNDARY = 0xffffU,
+
+ EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U,
+
+ EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U,
+};
+
+enum chip_type {
+ chip_504x,
+ chip_508x,
+ chip_5080,
+ chip_604x,
+ chip_608x,
+};
+
/* Command ReQuest Block: 32B */
struct mv_crqb {
u32 sg_addr;
@@ -252,14 +292,37 @@ struct mv_port_priv {
u32 pp_flags;
};
+struct mv_port_signal {
+ u32 amps;
+ u32 pre;
+};
+
+struct mv_host_priv;
+struct mv_hw_ops {
+ void (*phy_errata)(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int port);
+ void (*enable_leds)(struct mv_host_priv *hpriv, void __iomem *mmio);
+ void (*read_preamp)(struct mv_host_priv *hpriv, int idx,
+ void __iomem *mmio);
+ int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int n_hc);
+ void (*reset_flash)(struct mv_host_priv *hpriv, void __iomem *mmio);
+ void (*reset_bus)(struct pci_dev *pdev, void __iomem *mmio);
+};
+
struct mv_host_priv {
u32 hp_flags;
+ struct mv_port_signal signal[8];
+ const struct mv_hw_ops *ops;
};
static void mv_irq_clear(struct ata_port *ap);
static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
+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_set *host_set);
static int mv_port_start(struct ata_port *ap);
static void mv_port_stop(struct ata_port *ap);
@@ -270,6 +333,29 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
static void mv_eng_timeout(struct ata_port *ap);
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int port);
+static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio);
+static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
+ void __iomem *mmio);
+static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int n_hc);
+static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio);
+static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio);
+
+static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int port);
+static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio);
+static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx,
+ void __iomem *mmio);
+static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int n_hc);
+static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio);
+static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio);
+static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int port_no);
+static void mv_stop_and_reset(struct ata_port *ap);
+
static struct scsi_host_template mv_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -278,7 +364,7 @@ static struct scsi_host_template mv_sht = {
.eh_strategy_handler = ata_scsi_error,
.can_queue = MV_USE_Q_DEPTH,
.this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = MV_MAX_SG_CT,
+ .sg_tablesize = MV_MAX_SG_CT / 2,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
@@ -290,7 +376,34 @@ static struct scsi_host_template mv_sht = {
.ordered_flush = 1,
};
-static const struct ata_port_operations mv_ops = {
+static const struct ata_port_operations mv5_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,
+
+ .phy_reset = mv_phy_reset,
+
+ .qc_prep = mv_qc_prep,
+ .qc_issue = mv_qc_issue,
+
+ .eng_timeout = mv_eng_timeout,
+
+ .irq_handler = mv_interrupt,
+ .irq_clear = mv_irq_clear,
+
+ .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 = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
@@ -322,43 +435,52 @@ static struct ata_port_info mv_port_info[] = {
.sht = &mv_sht,
.host_flags = MV_COMMON_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */
- .port_ops = &mv_ops,
+ .udma_mask = 0x7f, /* udma0-6 */
+ .port_ops = &mv5_ops,
},
{ /* chip_508x */
.sht = &mv_sht,
.host_flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */
- .port_ops = &mv_ops,
+ .udma_mask = 0x7f, /* udma0-6 */
+ .port_ops = &mv5_ops,
+ },
+ { /* chip_5080 */
+ .sht = &mv_sht,
+ .host_flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0x7f, /* udma0-6 */
+ .port_ops = &mv5_ops,
},
{ /* chip_604x */
.sht = &mv_sht,
.host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
- .port_ops = &mv_ops,
+ .port_ops = &mv6_ops,
},
{ /* chip_608x */
.sht = &mv_sht,
- .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+ .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
MV_FLAG_DUAL_HC),
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
- .port_ops = &mv_ops,
+ .port_ops = &mv6_ops,
},
};
-static struct pci_device_id mv_pci_tbl[] = {
+static const struct pci_device_id mv_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5040), 0, 0, chip_504x},
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5041), 0, 0, chip_504x},
- {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_508x},
+ {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_5080},
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5081), 0, 0, chip_508x},
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6040), 0, 0, chip_604x},
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6041), 0, 0, chip_604x},
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6080), 0, 0, chip_608x},
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6081), 0, 0, chip_608x},
+
+ {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x0241), 0, 0, chip_604x},
{} /* terminate list */
};
@@ -369,6 +491,24 @@ static struct pci_driver mv_pci_driver = {
.remove = ata_pci_remove_one,
};
+static const struct mv_hw_ops mv5xxx_ops = {
+ .phy_errata = mv5_phy_errata,
+ .enable_leds = mv5_enable_leds,
+ .read_preamp = mv5_read_preamp,
+ .reset_hc = mv5_reset_hc,
+ .reset_flash = mv5_reset_flash,
+ .reset_bus = mv5_reset_bus,
+};
+
+static const struct mv_hw_ops mv6xxx_ops = {
+ .phy_errata = mv6_phy_errata,
+ .enable_leds = mv6_enable_leds,
+ .read_preamp = mv6_read_preamp,
+ .reset_hc = mv6_reset_hc,
+ .reset_flash = mv6_reset_flash,
+ .reset_bus = mv_reset_pci_bus,
+};
+
/*
* Functions
*/
@@ -384,11 +524,27 @@ static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc)
return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ));
}
+static inline unsigned int mv_hc_from_port(unsigned int port)
+{
+ return port >> MV_PORT_HC_SHIFT;
+}
+
+static inline unsigned int mv_hardport_from_port(unsigned int port)
+{
+ return port & MV_PORT_MASK;
+}
+
+static inline void __iomem *mv_hc_base_from_port(void __iomem *base,
+ unsigned int port)
+{
+ return mv_hc_base(base, mv_hc_from_port(port));
+}
+
static inline void __iomem *mv_port_base(void __iomem *base, unsigned int port)
{
- return (mv_hc_base(base, port >> MV_PORT_HC_SHIFT) +
- MV_SATAHC_ARBTR_REG_SZ +
- ((port & MV_PORT_MASK) * MV_PORT_REG_SZ));
+ return mv_hc_base_from_port(base, port) +
+ MV_SATAHC_ARBTR_REG_SZ +
+ (mv_hardport_from_port(port) * MV_PORT_REG_SZ);
}
static inline void __iomem *mv_ap_base(struct ata_port *ap)
@@ -396,9 +552,9 @@ static inline void __iomem *mv_ap_base(struct ata_port *ap)
return mv_port_base(ap->host_set->mmio_base, ap->port_no);
}
-static inline int mv_get_hc_count(unsigned long hp_flags)
+static inline int mv_get_hc_count(unsigned long host_flags)
{
- return ((hp_flags & MV_FLAG_DUAL_HC) ? 2 : 1);
+ return ((host_flags & MV_FLAG_DUAL_HC) ? 2 : 1);
}
static void mv_irq_clear(struct ata_port *ap)
@@ -450,7 +606,7 @@ static void mv_stop_dma(struct ata_port *ap)
} else {
assert(!(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS)));
}
-
+
/* now properly wait for the eDMA to stop */
for (i = 1000; i > 0; i--) {
reg = readl(port_mmio + EDMA_CMD_OFS);
@@ -501,7 +657,7 @@ static void mv_dump_all_regs(void __iomem *mmio_base, int port,
struct pci_dev *pdev)
{
#ifdef ATA_DEBUG
- void __iomem *hc_base = mv_hc_base(mmio_base,
+ void __iomem *hc_base = mv_hc_base(mmio_base,
port >> MV_PORT_HC_SHIFT);
void __iomem *port_base;
int start_port, num_ports, p, start_hc, num_hcs, hc;
@@ -515,7 +671,7 @@ static void mv_dump_all_regs(void __iomem *mmio_base, int port,
start_port = port;
num_ports = num_hcs = 1;
}
- DPRINTK("All registers for port(s) %u-%u:\n", start_port,
+ DPRINTK("All registers for port(s) %u-%u:\n", start_port,
num_ports > 1 ? num_ports - 1 : start_port);
if (NULL != pdev) {
@@ -583,70 +739,6 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
}
/**
- * mv_global_soft_reset - Perform the 6xxx global soft reset
- * @mmio_base: base address of the HBA
- *
- * This routine only applies to 6xxx parts.
- *
- * LOCKING:
- * Inherited from caller.
- */
-static int mv_global_soft_reset(void __iomem *mmio_base)
-{
- void __iomem *reg = mmio_base + PCI_MAIN_CMD_STS_OFS;
- int i, rc = 0;
- u32 t;
-
- /* Following procedure defined in PCI "main command and status
- * register" table.
- */
- t = readl(reg);
- writel(t | STOP_PCI_MASTER, reg);
-
- for (i = 0; i < 1000; i++) {
- udelay(1);
- t = readl(reg);
- if (PCI_MASTER_EMPTY & t) {
- break;
- }
- }
- if (!(PCI_MASTER_EMPTY & t)) {
- printk(KERN_ERR DRV_NAME ": PCI master won't flush\n");
- rc = 1;
- goto done;
- }
-
- /* set reset */
- i = 5;
- do {
- writel(t | GLOB_SFT_RST, reg);
- t = readl(reg);
- udelay(1);
- } while (!(GLOB_SFT_RST & t) && (i-- > 0));
-
- if (!(GLOB_SFT_RST & t)) {
- printk(KERN_ERR DRV_NAME ": can't set global reset\n");
- rc = 1;
- goto done;
- }
-
- /* clear reset and *reenable the PCI master* (not mentioned in spec) */
- i = 5;
- do {
- writel(t & ~(GLOB_SFT_RST | STOP_PCI_MASTER), reg);
- t = readl(reg);
- udelay(1);
- } while ((GLOB_SFT_RST & t) && (i-- > 0));
-
- if (GLOB_SFT_RST & t) {
- printk(KERN_ERR DRV_NAME ": can't clear global reset\n");
- rc = 1;
- }
-done:
- return rc;
-}
-
-/**
* mv_host_stop - Host specific cleanup/stop routine.
* @host_set: host data structure
*
@@ -699,7 +791,7 @@ static int mv_port_start(struct ata_port *ap)
goto err_out;
memset(pp, 0, sizeof(*pp));
- mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma,
+ mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma,
GFP_KERNEL);
if (!mem)
goto err_out_pp;
@@ -709,7 +801,7 @@ static int mv_port_start(struct ata_port *ap)
if (rc)
goto err_out_priv;
- /* First item in chunk of DMA memory:
+ /* First item in chunk of DMA memory:
* 32-slot command request table (CRQB), 32 bytes each in size
*/
pp->crqb = mem;
@@ -717,7 +809,7 @@ static int mv_port_start(struct ata_port *ap)
mem += MV_CRQB_Q_SZ;
mem_dma += MV_CRQB_Q_SZ;
- /* Second item:
+ /* Second item:
* 32-slot command response table (CRPB), 8 bytes each in size
*/
pp->crpb = mem;
@@ -731,18 +823,18 @@ static int mv_port_start(struct ata_port *ap)
pp->sg_tbl = mem;
pp->sg_tbl_dma = mem_dma;
- writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT |
+ writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT |
EDMA_CFG_WR_BUFF_LEN, port_mmio + EDMA_CFG_OFS);
writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
- writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK,
+ writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK,
port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
- writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK,
+ writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK,
port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
pp->req_producer = pp->rsp_consumer = 0;
@@ -803,20 +895,30 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
struct scatterlist *sg;
ata_for_each_sg(sg, qc) {
- u32 sg_len;
dma_addr_t addr;
+ u32 sg_len, len, offset;
addr = sg_dma_address(sg);
sg_len = sg_dma_len(sg);
- pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff);
- pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
- assert(0 == (sg_len & ~MV_DMA_BOUNDARY));
- pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len);
- if (ata_sg_is_last(sg, qc))
- pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
+ while (sg_len) {
+ offset = addr & MV_DMA_BOUNDARY;
+ len = sg_len;
+ if ((offset + sg_len) > 0x10000)
+ len = 0x10000 - offset;
+
+ pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff);
+ pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
+ pp->sg_tbl[i].flags_size = cpu_to_le32(len);
+
+ sg_len -= len;
+ addr += len;
+
+ if (!sg_len && ata_sg_is_last(sg, qc))
+ pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
- i++;
+ i++;
+ }
}
}
@@ -857,7 +959,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
}
/* the req producer index should be the same as we remember it */
- assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >>
+ assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >>
EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
pp->req_producer);
@@ -869,9 +971,9 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
assert(MV_MAX_Q_DEPTH > qc->tag);
flags |= qc->tag << CRQB_TAG_SHIFT;
- pp->crqb[pp->req_producer].sg_addr =
+ pp->crqb[pp->req_producer].sg_addr =
cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
- pp->crqb[pp->req_producer].sg_addr_hi =
+ pp->crqb[pp->req_producer].sg_addr_hi =
cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16);
pp->crqb[pp->req_producer].ctrl_flags = cpu_to_le16(flags);
@@ -894,7 +996,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
#ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */
case ATA_CMD_FPDMA_READ:
case ATA_CMD_FPDMA_WRITE:
- mv_crqb_pack_cmd(cw++, tf->hob_feature, ATA_REG_FEATURE, 0);
+ mv_crqb_pack_cmd(cw++, tf->hob_feature, ATA_REG_FEATURE, 0);
mv_crqb_pack_cmd(cw++, tf->feature, ATA_REG_FEATURE, 0);
break;
#endif /* FIXME: remove this line when NCQ added */
@@ -960,7 +1062,7 @@ static int mv_qc_issue(struct ata_queued_cmd *qc)
pp->req_producer);
/* until we do queuing, the queue should be empty at this point */
assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
- ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >>
+ ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >>
EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
mv_inc_q_index(&pp->req_producer); /* now incr producer index */
@@ -997,15 +1099,15 @@ static u8 mv_get_crpb_status(struct ata_port *ap)
out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
/* the response consumer index should be the same as we remember it */
- assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
pp->rsp_consumer);
/* increment our consumer index... */
pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer);
-
+
/* and, until we do NCQ, there should only be 1 CRPB waiting */
- assert(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >>
- EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ assert(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >>
+ EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
pp->rsp_consumer);
/* write out our inc'd consumer index so EDMA knows we're caught up */
@@ -1053,7 +1155,7 @@ static void mv_err_intr(struct ata_port *ap)
/* check for fatal here and recover if needed */
if (EDMA_ERR_FATAL & edma_err_cause) {
- mv_phy_reset(ap);
+ mv_stop_and_reset(ap);
}
}
@@ -1118,6 +1220,10 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
handled++;
}
+ if (ap &&
+ (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)))
+ continue;
+
err_mask = ac_err_mask(ata_status);
shift = port << 1; /* (port * 2) */
@@ -1129,14 +1235,15 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
err_mask |= AC_ERR_OTHER;
handled++;
}
-
+
if (handled && ap) {
qc = ata_qc_from_tag(ap, ap->active_tag);
if (NULL != qc) {
VPRINTK("port %u IRQ found for qc, "
"ata_status 0x%x\n", port,ata_status);
/* mark qc status appropriately */
- ata_qc_complete(qc, err_mask);
+ if (!(qc->tf.ctl & ATA_NIEN))
+ ata_qc_complete(qc, err_mask);
}
}
}
@@ -1144,7 +1251,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
}
/**
- * mv_interrupt -
+ * mv_interrupt -
* @irq: unused
* @dev_instance: private data; in this case the host structure
* @regs: unused
@@ -1154,7 +1261,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
* routine to handle. Also check for PCI errors which are only
* reported here.
*
- * LOCKING:
+ * LOCKING:
* This routine holds the host_set lock while processing pending
* interrupts.
*/
@@ -1200,8 +1307,422 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
return IRQ_RETVAL(handled);
}
+static void __iomem *mv5_phy_base(void __iomem *mmio, unsigned int port)
+{
+ void __iomem *hc_mmio = mv_hc_base_from_port(mmio, port);
+ unsigned long ofs = (mv_hardport_from_port(port) + 1) * 0x100UL;
+
+ return hc_mmio + ofs;
+}
+
+static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
+{
+ unsigned int ofs;
+
+ switch (sc_reg_in) {
+ case SCR_STATUS:
+ case SCR_ERROR:
+ case SCR_CONTROL:
+ ofs = sc_reg_in * sizeof(u32);
+ break;
+ default:
+ ofs = 0xffffffffU;
+ break;
+ }
+ return ofs;
+}
+
+static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in)
+{
+ void __iomem *mmio = mv5_phy_base(ap->host_set->mmio_base, ap->port_no);
+ unsigned int ofs = mv5_scr_offset(sc_reg_in);
+
+ if (ofs != 0xffffffffU)
+ return readl(mmio + 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_set->mmio_base, ap->port_no);
+ unsigned int ofs = mv5_scr_offset(sc_reg_in);
+
+ if (ofs != 0xffffffffU)
+ writelfl(val, mmio + ofs);
+}
+
+static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio)
+{
+ u8 rev_id;
+ int early_5080;
+
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
+
+ early_5080 = (pdev->device == 0x5080) && (rev_id == 0);
+
+ if (!early_5080) {
+ u32 tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL);
+ tmp |= (1 << 0);
+ writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL);
+ }
+
+ mv_reset_pci_bus(pdev, mmio);
+}
+
+static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
+{
+ writel(0x0fcfffff, mmio + MV_FLASH_CTL);
+}
+
+static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
+ void __iomem *mmio)
+{
+ void __iomem *phy_mmio = mv5_phy_base(mmio, idx);
+ u32 tmp;
+
+ tmp = readl(phy_mmio + MV5_PHY_MODE);
+
+ hpriv->signal[idx].pre = tmp & 0x1800; /* bits 12:11 */
+ hpriv->signal[idx].amps = tmp & 0xe0; /* bits 7:5 */
+}
+
+static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio)
+{
+ u32 tmp;
+
+ writel(0, mmio + MV_GPIO_PORT_CTL);
+
+ /* FIXME: handle MV_HP_ERRATA_50XXB2 errata */
+
+ tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL);
+ tmp |= ~(1 << 0);
+ writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL);
+}
+
+static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int port)
+{
+ void __iomem *phy_mmio = mv5_phy_base(mmio, port);
+ const u32 mask = (1<<12) | (1<<11) | (1<<7) | (1<<6) | (1<<5);
+ u32 tmp;
+ int fix_apm_sq = (hpriv->hp_flags & MV_HP_ERRATA_50XXB0);
+
+ if (fix_apm_sq) {
+ tmp = readl(phy_mmio + MV5_LT_MODE);
+ tmp |= (1 << 19);
+ writel(tmp, phy_mmio + MV5_LT_MODE);
+
+ tmp = readl(phy_mmio + MV5_PHY_CTL);
+ tmp &= ~0x3;
+ tmp |= 0x1;
+ writel(tmp, phy_mmio + MV5_PHY_CTL);
+ }
+
+ tmp = readl(phy_mmio + MV5_PHY_MODE);
+ tmp &= ~mask;
+ tmp |= hpriv->signal[port].pre;
+ tmp |= hpriv->signal[port].amps;
+ writel(tmp, phy_mmio + MV5_PHY_MODE);
+}
+
+
+#undef ZERO
+#define ZERO(reg) writel(0, port_mmio + (reg))
+static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int port)
+{
+ void __iomem *port_mmio = mv_port_base(mmio, port);
+
+ writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
+
+ mv_channel_reset(hpriv, mmio, port);
+
+ ZERO(0x028); /* command */
+ writel(0x11f, port_mmio + EDMA_CFG_OFS);
+ ZERO(0x004); /* timer */
+ ZERO(0x008); /* irq err cause */
+ ZERO(0x00c); /* irq err mask */
+ ZERO(0x010); /* rq bah */
+ ZERO(0x014); /* rq inp */
+ ZERO(0x018); /* rq outp */
+ ZERO(0x01c); /* respq bah */
+ ZERO(0x024); /* respq outp */
+ ZERO(0x020); /* respq inp */
+ ZERO(0x02c); /* test control */
+ writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
+}
+#undef ZERO
+
+#define ZERO(reg) writel(0, hc_mmio + (reg))
+static void mv5_reset_one_hc(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int hc)
+{
+ void __iomem *hc_mmio = mv_hc_base(mmio, hc);
+ u32 tmp;
+
+ ZERO(0x00c);
+ ZERO(0x010);
+ ZERO(0x014);
+ ZERO(0x018);
+
+ tmp = readl(hc_mmio + 0x20);
+ tmp &= 0x1c1c1c1c;
+ tmp |= 0x03030303;
+ writel(tmp, hc_mmio + 0x20);
+}
+#undef ZERO
+
+static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int n_hc)
+{
+ unsigned int hc, port;
+
+ for (hc = 0; hc < n_hc; hc++) {
+ for (port = 0; port < MV_PORTS_PER_HC; port++)
+ mv5_reset_hc_port(hpriv, mmio,
+ (hc * MV_PORTS_PER_HC) + port);
+
+ mv5_reset_one_hc(hpriv, mmio, hc);
+ }
+
+ return 0;
+}
+
+#undef ZERO
+#define ZERO(reg) writel(0, mmio + (reg))
+static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio)
+{
+ u32 tmp;
+
+ tmp = readl(mmio + MV_PCI_MODE);
+ tmp &= 0xff00ffff;
+ writel(tmp, mmio + MV_PCI_MODE);
+
+ ZERO(MV_PCI_DISC_TIMER);
+ ZERO(MV_PCI_MSI_TRIGGER);
+ writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT);
+ ZERO(HC_MAIN_IRQ_MASK_OFS);
+ ZERO(MV_PCI_SERR_MASK);
+ ZERO(PCI_IRQ_CAUSE_OFS);
+ ZERO(PCI_IRQ_MASK_OFS);
+ ZERO(MV_PCI_ERR_LOW_ADDRESS);
+ ZERO(MV_PCI_ERR_HIGH_ADDRESS);
+ ZERO(MV_PCI_ERR_ATTRIBUTE);
+ ZERO(MV_PCI_ERR_COMMAND);
+}
+#undef ZERO
+
+static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
+{
+ u32 tmp;
+
+ mv5_reset_flash(hpriv, mmio);
+
+ tmp = readl(mmio + MV_GPIO_PORT_CTL);
+ tmp &= 0x3;
+ tmp |= (1 << 5) | (1 << 6);
+ writel(tmp, mmio + MV_GPIO_PORT_CTL);
+}
+
+/**
+ * mv6_reset_hc - Perform the 6xxx global soft reset
+ * @mmio: base address of the HBA
+ *
+ * This routine only applies to 6xxx parts.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int n_hc)
+{
+ void __iomem *reg = mmio + PCI_MAIN_CMD_STS_OFS;
+ int i, rc = 0;
+ u32 t;
+
+ /* Following procedure defined in PCI "main command and status
+ * register" table.
+ */
+ t = readl(reg);
+ writel(t | STOP_PCI_MASTER, reg);
+
+ for (i = 0; i < 1000; i++) {
+ udelay(1);
+ t = readl(reg);
+ if (PCI_MASTER_EMPTY & t) {
+ break;
+ }
+ }
+ if (!(PCI_MASTER_EMPTY & t)) {
+ printk(KERN_ERR DRV_NAME ": PCI master won't flush\n");
+ rc = 1;
+ goto done;
+ }
+
+ /* set reset */
+ i = 5;
+ do {
+ writel(t | GLOB_SFT_RST, reg);
+ t = readl(reg);
+ udelay(1);
+ } while (!(GLOB_SFT_RST & t) && (i-- > 0));
+
+ if (!(GLOB_SFT_RST & t)) {
+ printk(KERN_ERR DRV_NAME ": can't set global reset\n");
+ rc = 1;
+ goto done;
+ }
+
+ /* clear reset and *reenable the PCI master* (not mentioned in spec) */
+ i = 5;
+ do {
+ writel(t & ~(GLOB_SFT_RST | STOP_PCI_MASTER), reg);
+ t = readl(reg);
+ udelay(1);
+ } while ((GLOB_SFT_RST & t) && (i-- > 0));
+
+ if (GLOB_SFT_RST & t) {
+ printk(KERN_ERR DRV_NAME ": can't clear global reset\n");
+ rc = 1;
+ }
+done:
+ return rc;
+}
+
+static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx,
+ void __iomem *mmio)
+{
+ void __iomem *port_mmio;
+ u32 tmp;
+
+ tmp = readl(mmio + MV_RESET_CFG);
+ if ((tmp & (1 << 0)) == 0) {
+ hpriv->signal[idx].amps = 0x7 << 8;
+ hpriv->signal[idx].pre = 0x1 << 5;
+ return;
+ }
+
+ port_mmio = mv_port_base(mmio, idx);
+ tmp = readl(port_mmio + PHY_MODE2);
+
+ hpriv->signal[idx].amps = tmp & 0x700; /* bits 10:8 */
+ hpriv->signal[idx].pre = tmp & 0xe0; /* bits 7:5 */
+}
+
+static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio)
+{
+ writel(0x00000060, mmio + MV_GPIO_PORT_CTL);
+}
+
+static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int port)
+{
+ void __iomem *port_mmio = mv_port_base(mmio, port);
+
+ u32 hp_flags = hpriv->hp_flags;
+ int fix_phy_mode2 =
+ hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0);
+ int fix_phy_mode4 =
+ hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0);
+ u32 m2, tmp;
+
+ if (fix_phy_mode2) {
+ m2 = readl(port_mmio + PHY_MODE2);
+ m2 &= ~(1 << 16);
+ m2 |= (1 << 31);
+ writel(m2, port_mmio + PHY_MODE2);
+
+ udelay(200);
+
+ m2 = readl(port_mmio + PHY_MODE2);
+ m2 &= ~((1 << 16) | (1 << 31));
+ writel(m2, port_mmio + PHY_MODE2);
+
+ udelay(200);
+ }
+
+ /* who knows what this magic does */
+ tmp = readl(port_mmio + PHY_MODE3);
+ tmp &= ~0x7F800000;
+ tmp |= 0x2A800000;
+ writel(tmp, port_mmio + PHY_MODE3);
+
+ if (fix_phy_mode4) {
+ u32 m4;
+
+ m4 = readl(port_mmio + PHY_MODE4);
+
+ if (hp_flags & MV_HP_ERRATA_60X1B2)
+ tmp = readl(port_mmio + 0x310);
+
+ m4 = (m4 & ~(1 << 1)) | (1 << 0);
+
+ writel(m4, port_mmio + PHY_MODE4);
+
+ if (hp_flags & MV_HP_ERRATA_60X1B2)
+ writel(tmp, port_mmio + 0x310);
+ }
+
+ /* Revert values of pre-emphasis and signal amps to the saved ones */
+ m2 = readl(port_mmio + PHY_MODE2);
+
+ m2 &= ~MV_M2_PREAMP_MASK;
+ m2 |= hpriv->signal[port].amps;
+ m2 |= hpriv->signal[port].pre;
+ m2 &= ~(1 << 16);
+
+ writel(m2, port_mmio + PHY_MODE2);
+}
+
+static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
+ unsigned int port_no)
+{
+ void __iomem *port_mmio = mv_port_base(mmio, port_no);
+
+ writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
+
+ if (IS_60XX(hpriv)) {
+ u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
+ ifctl |= (1 << 12) | (1 << 7);
+ writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL);
+ }
+
+ udelay(25); /* allow reset propagation */
+
+ /* Spec never mentions clearing the bit. Marvell's driver does
+ * clear the bit, however.
+ */
+ writelfl(0, port_mmio + EDMA_CMD_OFS);
+
+ hpriv->ops->phy_errata(hpriv, mmio, port_no);
+
+ if (IS_50XX(hpriv))
+ mdelay(1);
+}
+
+static void mv_stop_and_reset(struct ata_port *ap)
+{
+ struct mv_host_priv *hpriv = ap->host_set->private_data;
+ void __iomem *mmio = ap->host_set->mmio_base;
+
+ mv_stop_dma(ap);
+
+ mv_channel_reset(hpriv, mmio, ap->port_no);
+
+ __mv_phy_reset(ap, 0);
+}
+
+static inline void __msleep(unsigned int msec, int can_sleep)
+{
+ if (can_sleep)
+ msleep(msec);
+ else
+ mdelay(msec);
+}
+
/**
- * mv_phy_reset - Perform eDMA reset followed by COMRESET
+ * __mv_phy_reset - Perform eDMA reset followed by COMRESET
* @ap: ATA channel to manipulate
*
* Part of this is taken from __sata_phy_reset and modified to
@@ -1211,41 +1732,47 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
* Inherited from caller. This is coded to safe to call at
* interrupt level, i.e. it does not sleep.
*/
-static void mv_phy_reset(struct ata_port *ap)
+static void __mv_phy_reset(struct ata_port *ap, int can_sleep)
{
+ struct mv_port_priv *pp = ap->private_data;
+ struct mv_host_priv *hpriv = ap->host_set->private_data;
void __iomem *port_mmio = mv_ap_base(ap);
struct ata_taskfile tf;
struct ata_device *dev = &ap->device[0];
unsigned long timeout;
+ int retry = 5;
+ u32 sstatus;
VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio);
- mv_stop_dma(ap);
-
- writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
- udelay(25); /* allow reset propagation */
-
- /* Spec never mentions clearing the bit. Marvell's driver does
- * clear the bit, however.
- */
- writelfl(0, port_mmio + EDMA_CMD_OFS);
-
- VPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
+ DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
"SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
- /* proceed to init communications via the scr_control reg */
+ /* Issue COMRESET via SControl */
+comreset_retry:
scr_write_flush(ap, SCR_CONTROL, 0x301);
- mdelay(1);
+ __msleep(1, can_sleep);
+
scr_write_flush(ap, SCR_CONTROL, 0x300);
- timeout = jiffies + (HZ * 1);
+ __msleep(20, can_sleep);
+
+ timeout = jiffies + msecs_to_jiffies(200);
do {
- mdelay(10);
- if ((scr_read(ap, SCR_STATUS) & 0xf) != 1)
+ sstatus = scr_read(ap, SCR_STATUS) & 0x3;
+ if ((sstatus == 3) || (sstatus == 0))
break;
+
+ __msleep(1, can_sleep);
} while (time_before(jiffies, timeout));
- VPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
+ /* work around errata */
+ if (IS_60XX(hpriv) &&
+ (sstatus != 0x0) && (sstatus != 0x113) && (sstatus != 0x123) &&
+ (retry-- > 0))
+ goto comreset_retry;
+
+ DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
"SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
@@ -1259,6 +1786,21 @@ static void mv_phy_reset(struct ata_port *ap)
}
ap->cbl = ATA_CBL_SATA;
+ /* even after SStatus reflects that device is ready,
+ * it seems to take a while for link to be fully
+ * established (and thus Status no longer 0x80/0x7F),
+ * so we poll a bit for that, here.
+ */
+ retry = 20;
+ while (1) {
+ u8 drv_stat = ata_check_status(ap);
+ if ((drv_stat != 0x80) && (drv_stat != 0x7f))
+ break;
+ __msleep(500, can_sleep);
+ if (retry-- <= 0)
+ 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);
@@ -1269,9 +1811,19 @@ static void mv_phy_reset(struct ata_port *ap)
VPRINTK("Port disabled post-sig: No device present.\n");
ata_port_disable(ap);
}
+
+ writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+
+ pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+
VPRINTK("EXIT\n");
}
+static void mv_phy_reset(struct ata_port *ap)
+{
+ __mv_phy_reset(ap, 1);
+}
+
/**
* mv_eng_timeout - Routine called by libata when SCSI times out I/O
* @ap: ATA channel to manipulate
@@ -1289,16 +1841,16 @@ static void mv_eng_timeout(struct ata_port *ap)
printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id);
DPRINTK("All regs @ start of eng_timeout\n");
- mv_dump_all_regs(ap->host_set->mmio_base, ap->port_no,
+ mv_dump_all_regs(ap->host_set->mmio_base, ap->port_no,
to_pci_dev(ap->host_set->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_set->mmio_base, ap, qc, qc->scsicmd,
+ ap->host_set->mmio_base, ap, qc, qc->scsicmd,
&qc->scsicmd->cmnd);
mv_err_intr(ap);
- mv_phy_reset(ap);
+ mv_stop_and_reset(ap);
if (!qc) {
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
@@ -1334,17 +1886,17 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
unsigned long shd_base = (unsigned long) port_mmio + SHD_BLK_OFS;
unsigned serr_ofs;
- /* PIO related setup
+ /* PIO related setup
*/
port->data_addr = shd_base + (sizeof(u32) * ATA_REG_DATA);
- port->error_addr =
+ port->error_addr =
port->feature_addr = shd_base + (sizeof(u32) * ATA_REG_ERR);
port->nsect_addr = shd_base + (sizeof(u32) * ATA_REG_NSECT);
port->lbal_addr = shd_base + (sizeof(u32) * ATA_REG_LBAL);
port->lbam_addr = shd_base + (sizeof(u32) * ATA_REG_LBAM);
port->lbah_addr = shd_base + (sizeof(u32) * ATA_REG_LBAH);
port->device_addr = shd_base + (sizeof(u32) * ATA_REG_DEVICE);
- port->status_addr =
+ port->status_addr =
port->command_addr = shd_base + (sizeof(u32) * ATA_REG_STATUS);
/* special case: control/altstatus doesn't have ATA_REG_ address */
port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS;
@@ -1360,14 +1912,92 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
/* unmask all EDMA error interrupts */
writelfl(~0, port_mmio + EDMA_ERR_IRQ_MASK_OFS);
- VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n",
+ VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n",
readl(port_mmio + EDMA_CFG_OFS),
readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS),
readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
}
+static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
+ unsigned int board_idx)
+{
+ u8 rev_id;
+ u32 hp_flags = hpriv->hp_flags;
+
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
+
+ switch(board_idx) {
+ case chip_5080:
+ hpriv->ops = &mv5xxx_ops;
+ hp_flags |= MV_HP_50XX;
+
+ switch (rev_id) {
+ case 0x1:
+ hp_flags |= MV_HP_ERRATA_50XXB0;
+ break;
+ case 0x3:
+ hp_flags |= MV_HP_ERRATA_50XXB2;
+ break;
+ default:
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "Applying 50XXB2 workarounds to unknown rev\n");
+ hp_flags |= MV_HP_ERRATA_50XXB2;
+ break;
+ }
+ break;
+
+ case chip_504x:
+ case chip_508x:
+ hpriv->ops = &mv5xxx_ops;
+ hp_flags |= MV_HP_50XX;
+
+ switch (rev_id) {
+ case 0x0:
+ hp_flags |= MV_HP_ERRATA_50XXB0;
+ break;
+ case 0x3:
+ hp_flags |= MV_HP_ERRATA_50XXB2;
+ break;
+ default:
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "Applying B2 workarounds to unknown rev\n");
+ hp_flags |= MV_HP_ERRATA_50XXB2;
+ break;
+ }
+ break;
+
+ case chip_604x:
+ case chip_608x:
+ hpriv->ops = &mv6xxx_ops;
+
+ switch (rev_id) {
+ case 0x7:
+ hp_flags |= MV_HP_ERRATA_60X1B2;
+ break;
+ case 0x9:
+ hp_flags |= MV_HP_ERRATA_60X1C0;
+ break;
+ default:
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "Applying B2 workarounds to unknown rev\n");
+ hp_flags |= MV_HP_ERRATA_60X1B2;
+ break;
+ }
+ break;
+
+ default:
+ printk(KERN_ERR DRV_NAME ": BUG: invalid board index %u\n", board_idx);
+ return 1;
+ }
+
+ hpriv->hp_flags = hp_flags;
+
+ return 0;
+}
+
/**
- * mv_host_init - Perform some early initialization of the host.
+ * mv_init_host - Perform some early initialization of the host.
+ * @pdev: host PCI device
* @probe_ent: early data struct representing the host
*
* If possible, do an early global reset of the host. Then do
@@ -1376,23 +2006,48 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
* LOCKING:
* Inherited from caller.
*/
-static int mv_host_init(struct ata_probe_ent *probe_ent)
+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 *port_mmio;
+ struct mv_host_priv *hpriv = probe_ent->private_data;
- if ((MV_FLAG_GLBL_SFT_RST & probe_ent->host_flags) &&
- mv_global_soft_reset(probe_ent->mmio_base)) {
- rc = 1;
+ /* global interrupt mask */
+ writel(0, mmio + HC_MAIN_IRQ_MASK_OFS);
+
+ rc = mv_chip_id(pdev, hpriv, board_idx);
+ if (rc)
goto done;
- }
n_hc = mv_get_hc_count(probe_ent->host_flags);
probe_ent->n_ports = MV_PORTS_PER_HC * n_hc;
+ for (port = 0; port < probe_ent->n_ports; port++)
+ hpriv->ops->read_preamp(hpriv, port, mmio);
+
+ rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
+ if (rc)
+ goto done;
+
+ hpriv->ops->reset_flash(hpriv, mmio);
+ hpriv->ops->reset_bus(pdev, mmio);
+ hpriv->ops->enable_leds(hpriv, mmio);
+
for (port = 0; port < probe_ent->n_ports; port++) {
- port_mmio = mv_port_base(mmio, port);
+ if (IS_60XX(hpriv)) {
+ void __iomem *port_mmio = mv_port_base(mmio, port);
+
+ u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
+ ifctl |= (1 << 12);
+ writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL);
+ }
+
+ hpriv->ops->phy_errata(hpriv, mmio, port);
+ }
+
+ for (port = 0; port < probe_ent->n_ports; port++) {
+ void __iomem *port_mmio = mv_port_base(mmio, port);
mv_port_init(&probe_ent->port[port], port_mmio);
}
@@ -1416,11 +2071,12 @@ static int mv_host_init(struct ata_probe_ent *probe_ent)
writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x "
- "PCI int cause/mask=0x%08x/0x%08x\n",
+ "PCI int cause/mask=0x%08x/0x%08x\n",
readl(mmio + HC_MAIN_IRQ_CAUSE_OFS),
readl(mmio + HC_MAIN_IRQ_MASK_OFS),
readl(mmio + PCI_IRQ_CAUSE_OFS),
readl(mmio + PCI_IRQ_MASK_OFS));
+
done:
return rc;
}
@@ -1456,7 +2112,7 @@ static void mv_print_info(struct ata_probe_ent *probe_ent)
dev_printk(KERN_INFO, &pdev->dev,
"%u slots %u ports %s mode IRQ via %s\n",
- (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports,
+ (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports,
scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
}
@@ -1526,7 +2182,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->private_data = hpriv;
/* initialize adapter */
- rc = mv_host_init(probe_ent);
+ rc = mv_init_host(pdev, probe_ent, board_idx);
if (rc) {
goto err_out_hpriv;
}
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index 37a4fae..4954896 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -137,7 +137,7 @@ enum nv_host_type
CK804
};
-static struct pci_device_id nv_pci_tbl[] = {
+static const struct pci_device_id nv_pci_tbl[] = {
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE2 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 9edc9d9..8a8e3e3 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -46,7 +46,7 @@
#include "sata_promise.h"
#define DRV_NAME "sata_promise"
-#define DRV_VERSION "1.02"
+#define DRV_VERSION "1.03"
enum {
@@ -193,7 +193,7 @@ static struct ata_port_info pdc_port_info[] = {
},
};
-static struct pci_device_id pdc_ata_pci_tbl[] = {
+static const struct pci_device_id pdc_ata_pci_tbl[] = {
{ PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index d274ab2..a8987f5 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -41,7 +41,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_qstor"
-#define DRV_VERSION "0.04"
+#define DRV_VERSION "0.05"
enum {
QS_PORTS = 4,
@@ -184,7 +184,7 @@ static struct ata_port_info qs_port_info[] = {
},
};
-static struct pci_device_id qs_ata_pci_tbl[] = {
+static const struct pci_device_id qs_ata_pci_tbl[] = {
{ PCI_VENDOR_ID_PDC, 0x2068, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2068_idx },
@@ -268,7 +268,7 @@ static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
writel(val, (void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8)));
}
-static void qs_fill_sg(struct ata_queued_cmd *qc)
+static unsigned int qs_fill_sg(struct ata_queued_cmd *qc)
{
struct scatterlist *sg;
struct ata_port *ap = qc->ap;
@@ -296,6 +296,8 @@ static void qs_fill_sg(struct ata_queued_cmd *qc)
(unsigned long long)addr, len);
nelem++;
}
+
+ return nelem;
}
static void qs_qc_prep(struct ata_queued_cmd *qc)
@@ -304,6 +306,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc)
u8 dflags = QS_DF_PORD, *buf = pp->pkt;
u8 hflags = QS_HF_DAT | QS_HF_IEN | QS_HF_VLD;
u64 addr;
+ unsigned int nelem;
VPRINTK("ENTER\n");
@@ -313,7 +316,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc)
return;
}
- qs_fill_sg(qc);
+ nelem = qs_fill_sg(qc);
if ((qc->tf.flags & ATA_TFLAG_WRITE))
hflags |= QS_HF_DIRO;
@@ -324,7 +327,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc)
buf[ 0] = QS_HCB_HDR;
buf[ 1] = hflags;
*(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nsect * ATA_SECT_SIZE);
- *(__le32 *)(&buf[ 8]) = cpu_to_le32(qc->n_elem);
+ *(__le32 *)(&buf[ 8]) = cpu_to_le32(nelem);
addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES;
*(__le64 *)(&buf[16]) = cpu_to_le64(addr);
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index d0e3c3c..3609186 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -87,7 +87,7 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static void sil_post_set_mode (struct ata_port *ap);
-static struct pci_device_id sil_pci_tbl[] = {
+static const struct pci_device_id sil_pci_tbl[] = {
{ 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
{ 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
{ 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 4682a50..e0d6f19 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -5,17 +5,6 @@
*
* Based on preview driver from Silicon Image.
*
- * NOTE: No NCQ/ATAPI support yet. The preview driver didn't support
- * NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make
- * those work. Enabling those shouldn't be difficult. Basic
- * structure is all there (in libata-dev tree). If you have any
- * information about this hardware, please contact me or linux-ide.
- * Info is needed on...
- *
- * - How to issue tagged commands and turn on sactive on issue accordingly.
- * - Where to put an ATAPI command and how to tell the device to send it.
- * - How to enable/use 64bit.
- *
* 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
@@ -42,7 +31,7 @@
#include <asm/io.h>
#define DRV_NAME "sata_sil24"
-#define DRV_VERSION "0.22" /* Silicon Image's preview driver was 0.10 */
+#define DRV_VERSION "0.23"
/*
* Port request block (PRB) 32 bytes
@@ -139,6 +128,7 @@ enum {
PORT_CS_DEV_RST = (1 << 1), /* device reset */
PORT_CS_INIT = (1 << 2), /* port initialize */
PORT_CS_IRQ_WOC = (1 << 3), /* interrupt write one to clear */
+ PORT_CS_CDB16 = (1 << 5), /* 0=12b cdb, 1=16b cdb */
PORT_CS_RESUME = (1 << 6), /* port resume */
PORT_CS_32BIT_ACTV = (1 << 10), /* 32-bit activation */
PORT_CS_PM_EN = (1 << 13), /* port multiplier enable */
@@ -188,11 +178,29 @@ enum {
PORT_CERR_XFR_PCIPERR = 35, /* PSD ecode 11 - PCI prity err during transfer */
PORT_CERR_SENDSERVICE = 36, /* FIS received while sending service */
+ /* bits of PRB control field */
+ PRB_CTRL_PROTOCOL = (1 << 0), /* override def. ATA protocol */
+ PRB_CTRL_PACKET_READ = (1 << 4), /* PACKET cmd read */
+ PRB_CTRL_PACKET_WRITE = (1 << 5), /* PACKET cmd write */
+ PRB_CTRL_NIEN = (1 << 6), /* Mask completion irq */
+ PRB_CTRL_SRST = (1 << 7), /* Soft reset request (ign BSY?) */
+
+ /* PRB protocol field */
+ PRB_PROT_PACKET = (1 << 0),
+ PRB_PROT_TCQ = (1 << 1),
+ PRB_PROT_NCQ = (1 << 2),
+ PRB_PROT_READ = (1 << 3),
+ PRB_PROT_WRITE = (1 << 4),
+ PRB_PROT_TRANSPARENT = (1 << 5),
+
/*
* Other constants
*/
SGE_TRM = (1 << 31), /* Last SGE in chain */
- PRB_SOFT_RST = (1 << 7), /* Soft reset request (ign BSY?) */
+ SGE_LNK = (1 << 30), /* linked list
+ Points to SGT, not SGE */
+ SGE_DRD = (1 << 29), /* discard data read (/dev/null)
+ data address ignored */
/* board id */
BID_SIL3124 = 0,
@@ -202,11 +210,22 @@ enum {
IRQ_STAT_4PORTS = 0xf,
};
-struct sil24_cmd_block {
+struct sil24_ata_block {
struct sil24_prb prb;
struct sil24_sge sge[LIBATA_MAX_PRD];
};
+struct sil24_atapi_block {
+ struct sil24_prb prb;
+ u8 cdb[16];
+ struct sil24_sge sge[LIBATA_MAX_PRD - 1];
+};
+
+union sil24_cmd_block {
+ struct sil24_ata_block ata;
+ struct sil24_atapi_block atapi;
+};
+
/*
* ap->private_data
*
@@ -214,7 +233,7 @@ struct sil24_cmd_block {
* here from the previous interrupt.
*/
struct sil24_port_priv {
- struct sil24_cmd_block *cmd_block; /* 32 cmd blocks */
+ union sil24_cmd_block *cmd_block; /* 32 cmd blocks */
dma_addr_t cmd_block_dma; /* DMA base addr for them */
struct ata_taskfile tf; /* Cached taskfile registers */
};
@@ -225,6 +244,7 @@ struct sil24_host_priv {
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);
static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
@@ -240,7 +260,7 @@ static void sil24_port_stop(struct ata_port *ap);
static void sil24_host_stop(struct ata_host_set *host_set);
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
-static struct pci_device_id sil24_pci_tbl[] = {
+static const struct pci_device_id sil24_pci_tbl[] = {
{ 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
{ 0x1095, 0x3132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3132 },
{ 0x1095, 0x3131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
@@ -278,6 +298,8 @@ static struct scsi_host_template sil24_sht = {
static const struct ata_port_operations sil24_ops = {
.port_disable = ata_port_disable,
+ .dev_config = sil24_dev_config,
+
.check_status = sil24_check_status,
.check_altstatus = sil24_check_status,
.dev_select = ata_noop_dev_select,
@@ -314,7 +336,7 @@ static struct ata_port_info sil24_port_info[] = {
{
.sht = &sil24_sht,
.host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_SRST | ATA_FLAG_MMIO |
ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -325,7 +347,7 @@ static struct ata_port_info sil24_port_info[] = {
{
.sht = &sil24_sht,
.host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_SRST | ATA_FLAG_MMIO |
ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -336,7 +358,7 @@ static struct ata_port_info sil24_port_info[] = {
{
.sht = &sil24_sht,
.host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_SRST | ATA_FLAG_MMIO |
ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -345,6 +367,16 @@ static struct ata_port_info sil24_port_info[] = {
},
};
+static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
+{
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+
+ if (ap->cdb_len == 16)
+ writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
+ else
+ writel(PORT_CS_CDB16, port + PORT_CTRL_CLR);
+}
+
static inline void sil24_update_tf(struct ata_port *ap)
{
struct sil24_port_priv *pp = ap->private_data;
@@ -396,22 +428,73 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
*tf = pp->tf;
}
-static void sil24_phy_reset(struct ata_port *ap)
+static int sil24_issue_SRST(struct ata_port *ap)
{
- __sata_phy_reset(ap);
+ void __iomem *port = (void __iomem *)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;
+ u32 irq_enable, irq_stat;
+ int cnt;
+
+ /* temporarily turn off IRQs during SRST */
+ irq_enable = readl(port + PORT_IRQ_ENABLE_SET);
+ writel(irq_enable, port + PORT_IRQ_ENABLE_CLR);
+
/*
- * No ATAPI yet. Just unconditionally indicate ATA device.
- * If ATAPI device is attached, it will fail ATA_CMD_ID_ATA
- * and libata core will ignore the device.
+ * XXX: Not sure whether the following sleep is needed or not.
+ * The original driver had it. So....
*/
- if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
- ap->device[0].class = ATA_DEV_ATA;
+ msleep(10);
+
+ prb->ctrl = PRB_CTRL_SRST;
+ prb->fis[1] = 0; /* no PM yet */
+
+ writel((u32)paddr, port + PORT_CMD_ACTIVATE);
+
+ for (cnt = 0; cnt < 100; cnt++) {
+ irq_stat = readl(port + PORT_IRQ_STAT);
+ writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */
+
+ irq_stat >>= PORT_IRQ_RAW_SHIFT;
+ if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR))
+ break;
+
+ msleep(1);
+ }
+
+ /* restore IRQs */
+ writel(irq_enable, port + PORT_IRQ_ENABLE_SET);
+
+ if (!(irq_stat & PORT_IRQ_COMPLETE))
+ return -1;
+
+ /* update TF */
+ sil24_update_tf(ap);
+ return 0;
+}
+
+static void sil24_phy_reset(struct ata_port *ap)
+{
+ struct sil24_port_priv *pp = ap->private_data;
+
+ __sata_phy_reset(ap);
+ if (ap->flags & ATA_FLAG_PORT_DISABLED)
+ return;
+
+ if (sil24_issue_SRST(ap) < 0) {
+ printk(KERN_ERR DRV_NAME
+ " ata%u: SRST failed, disabling port\n", ap->id);
+ ap->ops->port_disable(ap);
+ return;
+ }
+
+ ap->device->class = ata_dev_classify(&pp->tf);
}
static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
- struct sil24_cmd_block *cb)
+ struct sil24_sge *sge)
{
- struct sil24_sge *sge = cb->sge;
struct scatterlist *sg;
unsigned int idx = 0;
@@ -432,23 +515,47 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct sil24_port_priv *pp = ap->private_data;
- struct sil24_cmd_block *cb = pp->cmd_block + qc->tag;
- struct sil24_prb *prb = &cb->prb;
+ union sil24_cmd_block *cb = pp->cmd_block + qc->tag;
+ struct sil24_prb *prb;
+ struct sil24_sge *sge;
switch (qc->tf.protocol) {
case ATA_PROT_PIO:
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
+ prb = &cb->ata.prb;
+ sge = cb->ata.sge;
+ prb->ctrl = 0;
+ break;
+
+ case ATA_PROT_ATAPI:
+ case ATA_PROT_ATAPI_DMA:
+ case ATA_PROT_ATAPI_NODATA:
+ prb = &cb->atapi.prb;
+ sge = cb->atapi.sge;
+ memset(cb->atapi.cdb, 0, 32);
+ memcpy(cb->atapi.cdb, qc->cdb, ap->cdb_len);
+
+ if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) {
+ if (qc->tf.flags & ATA_TFLAG_WRITE)
+ prb->ctrl = PRB_CTRL_PACKET_WRITE;
+ else
+ prb->ctrl = PRB_CTRL_PACKET_READ;
+ } else
+ prb->ctrl = 0;
+
break;
+
default:
- /* ATAPI isn't supported yet */
+ prb = NULL; /* shut up, gcc */
+ sge = NULL;
BUG();
}
ata_tf_to_fis(&qc->tf, prb->fis, 0);
if (qc->flags & ATA_QCFLAG_DMAMAP)
- sil24_fill_sg(qc, cb);
+ sil24_fill_sg(qc, sge);
}
static int sil24_qc_issue(struct ata_queued_cmd *qc)
@@ -467,6 +574,31 @@ static void sil24_irq_clear(struct ata_port *ap)
/* unused */
}
+static int __sil24_restart_controller(void __iomem *port)
+{
+ u32 tmp;
+ int cnt;
+
+ writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
+
+ /* Max ~10ms */
+ for (cnt = 0; cnt < 10000; cnt++) {
+ tmp = readl(port + PORT_CTRL_STAT);
+ if (tmp & PORT_CS_RDY)
+ return 0;
+ udelay(1);
+ }
+
+ return -1;
+}
+
+static void sil24_restart_controller(struct ata_port *ap)
+{
+ if (__sil24_restart_controller((void __iomem *)ap->ioaddr.cmd_addr))
+ printk(KERN_ERR DRV_NAME
+ " ata%u: failed to restart controller\n", ap->id);
+}
+
static int __sil24_reset_controller(void __iomem *port)
{
int cnt;
@@ -486,7 +618,11 @@ static int __sil24_reset_controller(void __iomem *port)
if (tmp & PORT_CS_DEV_RST)
return -1;
- return 0;
+
+ if (tmp & PORT_CS_RDY)
+ return 0;
+
+ return __sil24_restart_controller(port);
}
static void sil24_reset_controller(struct ata_port *ap)
@@ -548,9 +684,15 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
if (serror)
writel(serror, port + PORT_SERROR);
- printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n"
- " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
- ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
+ /*
+ * Don't log ATAPI device errors. They're supposed to happen
+ * and any serious errors will be logged using sense data by
+ * the SCSI layer.
+ */
+ if (ap->device[0].class != ATA_DEV_ATAPI || cmd_err > PORT_CERR_SDB)
+ printk("ata%u: error interrupt on port%d\n"
+ " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
+ ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) {
/*
@@ -558,6 +700,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
*/
sil24_update_tf(ap);
err_mask = ac_err_mask(pp->tf.command);
+ sil24_restart_controller(ap);
} else {
/*
* Other errors. libata currently doesn't have any
@@ -565,12 +708,11 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
* ATA_ERR.
*/
err_mask = AC_ERR_OTHER;
+ sil24_reset_controller(ap);
}
if (qc)
ata_qc_complete(qc, err_mask);
-
- sil24_reset_controller(ap);
}
static inline void sil24_host_intr(struct ata_port *ap)
@@ -646,7 +788,7 @@ static int sil24_port_start(struct ata_port *ap)
{
struct device *dev = ap->host_set->dev;
struct sil24_port_priv *pp;
- struct sil24_cmd_block *cb;
+ union sil24_cmd_block *cb;
size_t cb_size = sizeof(*cb);
dma_addr_t cb_dma;
int rc = -ENOMEM;
@@ -687,6 +829,7 @@ static void sil24_port_stop(struct ata_port *ap)
struct sil24_port_priv *pp = ap->private_data;
sil24_cblk_free(pp, dev);
+ ata_pad_free(ap, dev);
kfree(pp);
}
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 42d7c4e..32e1262 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -67,7 +67,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
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 struct pci_device_id sis_pci_tbl[] = {
+static const struct pci_device_id sis_pci_tbl[] = {
{ PCI_VENDOR_ID_SI, 0x180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
{ PCI_VENDOR_ID_SI, 0x181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
{ PCI_VENDOR_ID_SI, 0x182, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 9895d1c..6e7f7c8 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -54,7 +54,7 @@
#endif /* CONFIG_PPC_OF */
#define DRV_NAME "sata_svw"
-#define DRV_VERSION "1.06"
+#define DRV_VERSION "1.07"
/* Taskfile registers offsets */
#define K2_SATA_TF_CMD_OFFSET 0x00
@@ -466,7 +466,7 @@ err_out:
* 0x24a is device ID for BCM5785 (aka HT1000) HT southbridge integrated SATA
* controller
* */
-static struct pci_device_id k2_sata_pci_tbl[] = {
+static const struct pci_device_id k2_sata_pci_tbl[] = {
{ 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
{ 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
{ 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index d5a3878..dcc3ad9 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -46,7 +46,7 @@
#include "sata_promise.h"
#define DRV_NAME "sata_sx4"
-#define DRV_VERSION "0.7"
+#define DRV_VERSION "0.8"
enum {
@@ -229,7 +229,7 @@ static struct ata_port_info pdc_port_info[] = {
};
-static struct pci_device_id pdc_sata_pci_tbl[] = {
+static const struct pci_device_id pdc_sata_pci_tbl[] = {
{ PCI_VENDOR_ID_PROMISE, 0x6622, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_20621 },
{ } /* terminate list */
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index cf0baaa..b2422a0 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -55,7 +55,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
-static struct pci_device_id uli_pci_tbl[] = {
+static const struct pci_device_id uli_pci_tbl[] = {
{ PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 },
{ PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 },
{ PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 },
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index ab19d2b..c762156 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -75,7 +75,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
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 struct pci_device_id svia_pci_tbl[] = {
+static const struct pci_device_id svia_pci_tbl[] = {
{ 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
{ 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 },
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index ce8a2fd..fcfa486 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -47,7 +47,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_vsc"
-#define DRV_VERSION "1.0"
+#define DRV_VERSION "1.1"
/* Interrupt register offsets (from chip base address) */
#define VSC_SATA_INT_STAT_OFFSET 0x00
@@ -400,7 +400,7 @@ err_out:
* 0x8086/0x3200 is the Intel 31244, which is supposed to be identical
* compatibility is untested as of yet
*/
-static struct pci_device_id vsc_sata_pci_tbl[] = {
+static const struct pci_device_id vsc_sata_pci_tbl[] = {
{ 0x1725, 0x7174, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 },
{ 0x8086, 0x3200, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 },
{ }
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index b61fb12..3ded9da 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -178,7 +178,7 @@ struct sdebug_queued_cmd {
};
static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE];
-static Scsi_Host_Template sdebug_driver_template = {
+static struct scsi_host_template sdebug_driver_template = {
.proc_info = scsi_debug_proc_info,
.name = "SCSI DEBUG",
.info = scsi_debug_info,
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 0c5b02d..18c5d25 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -417,43 +417,15 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
}
/**
- * scsi_eh_times_out - timeout function for error handling.
- * @scmd: Cmd that is timing out.
- *
- * Notes:
- * During error handling, the kernel thread will be sleeping waiting
- * for some action to complete on the device. our only job is to
- * record that it timed out, and to wake up the thread.
- **/
-static void scsi_eh_times_out(struct scsi_cmnd *scmd)
-{
- scmd->eh_eflags |= SCSI_EH_REC_TIMEOUT;
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd:%p\n", __FUNCTION__,
- scmd));
-
- up(scmd->device->host->eh_action);
-}
-
-/**
* scsi_eh_done - Completion function for error handling.
* @scmd: Cmd that is done.
**/
static void scsi_eh_done(struct scsi_cmnd *scmd)
{
- /*
- * if the timeout handler is already running, then just set the
- * flag which says we finished late, and return. we have no
- * way of stopping the timeout handler from running, so we must
- * always defer to it.
- */
- if (del_timer(&scmd->eh_timeout)) {
- scmd->request->rq_status = RQ_SCSI_DONE;
-
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s scmd: %p result: %x\n",
- __FUNCTION__, scmd, scmd->result));
-
- up(scmd->device->host->eh_action);
- }
+ SCSI_LOG_ERROR_RECOVERY(3,
+ printk("%s scmd: %p result: %x\n",
+ __FUNCTION__, scmd, scmd->result));
+ complete(scmd->device->host->eh_action);
}
/**
@@ -461,10 +433,6 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
* @scmd: SCSI Cmd to send.
* @timeout: Timeout for cmd.
*
- * Notes:
- * The initialization of the structures is quite a bit different in
- * this case, and furthermore, there is a different completion handler
- * vs scsi_dispatch_cmd.
* Return value:
* SUCCESS or FAILED or NEEDS_RETRY
**/
@@ -472,24 +440,16 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
{
struct scsi_device *sdev = scmd->device;
struct Scsi_Host *shost = sdev->host;
- DECLARE_MUTEX_LOCKED(sem);
+ DECLARE_COMPLETION(done);
+ unsigned long timeleft;
unsigned long flags;
- int rtn = SUCCESS;
+ int rtn;
- /*
- * we will use a queued command if possible, otherwise we will
- * emulate the queuing and calling of completion function ourselves.
- */
if (sdev->scsi_level <= SCSI_2)
scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
(sdev->lun << 5 & 0xe0);
- scsi_add_timer(scmd, timeout, scsi_eh_times_out);
-
- /*
- * set up the semaphore so we wait for the command to complete.
- */
- shost->eh_action = &sem;
+ shost->eh_action = &done;
scmd->request->rq_status = RQ_SCSI_BUSY;
spin_lock_irqsave(shost->host_lock, flags);
@@ -497,47 +457,29 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
shost->hostt->queuecommand(scmd, scsi_eh_done);
spin_unlock_irqrestore(shost->host_lock, flags);
- down(&sem);
- scsi_log_completion(scmd, SUCCESS);
+ timeleft = wait_for_completion_timeout(&done, timeout);
+ scmd->request->rq_status = RQ_SCSI_DONE;
shost->eh_action = NULL;
- /*
- * see if timeout. if so, tell the host to forget about it.
- * in other words, we don't want a callback any more.
- */
- if (scmd->eh_eflags & SCSI_EH_REC_TIMEOUT) {
- scmd->eh_eflags &= ~SCSI_EH_REC_TIMEOUT;
-
- /*
- * as far as the low level driver is
- * concerned, this command is still active, so
- * we must give the low level driver a chance
- * to abort it. (db)
- *
- * 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);
-
- scmd->request->rq_status = RQ_SCSI_DONE;
- rtn = FAILED;
- }
+ scsi_log_completion(scmd, SUCCESS);
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd: %p, rtn:%x\n",
- __FUNCTION__, scmd, rtn));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ printk("%s: scmd: %p, timeleft: %ld\n",
+ __FUNCTION__, scmd, timeleft));
/*
- * now examine the actual status codes to see whether the command
- * actually did complete normally.
+ * If there is time left scsi_eh_done got called, and we will
+ * examine the actual status codes to see whether the command
+ * actually did complete normally, else tell the host to forget
+ * about this command.
*/
- if (rtn == SUCCESS) {
+ if (timeleft) {
rtn = scsi_eh_completed_normally(scmd);
SCSI_LOG_ERROR_RECOVERY(3,
printk("%s: scsi_eh_completed_normally %x\n",
__FUNCTION__, rtn));
+
switch (rtn) {
case SUCCESS:
case NEEDS_RETRY:
@@ -547,6 +489,15 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
rtn = FAILED;
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);
+ rtn = FAILED;
}
return rtn;
@@ -1571,50 +1522,41 @@ static void scsi_unjam_host(struct Scsi_Host *shost)
}
/**
- * scsi_error_handler - Handle errors/timeouts of SCSI cmds.
+ * scsi_error_handler - SCSI error handler thread
* @data: Host for which we are running.
*
* Notes:
- * This is always run in the context of a kernel thread. The idea is
- * that we start this thing up when the kernel starts up (one per host
- * that we detect), and it immediately goes to sleep and waits for some
- * event (i.e. failure). When this takes place, we have the job of
- * trying to unjam the bus and restarting things.
+ * This is the main error handling loop. This is run as a kernel thread
+ * for every SCSI host and handles all error handling activity.
**/
int scsi_error_handler(void *data)
{
- struct Scsi_Host *shost = (struct Scsi_Host *) data;
- int rtn;
+ struct Scsi_Host *shost = data;
current->flags |= PF_NOFREEZE;
-
/*
- * Note - we always use TASK_INTERRUPTIBLE even if the module
- * was loaded as part of the kernel. The reason is that
- * UNINTERRUPTIBLE would cause this thread to be counted in
- * the load average as a running process, and an interruptible
- * wait doesn't.
+ * We use TASK_INTERRUPTIBLE so that the thread is not
+ * counted against the load average as a running process.
+ * We never actually get interrupted because kthread_run
+ * disables singal delivery for the created thread.
*/
set_current_state(TASK_INTERRUPTIBLE);
while (!kthread_should_stop()) {
if (shost->host_failed == 0 ||
shost->host_failed != shost->host_busy) {
- SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
- " scsi_eh_%d"
- " sleeping\n",
- shost->host_no));
+ SCSI_LOG_ERROR_RECOVERY(1,
+ printk("Error handler scsi_eh_%d sleeping\n",
+ shost->host_no));
schedule();
set_current_state(TASK_INTERRUPTIBLE);
continue;
}
__set_current_state(TASK_RUNNING);
- SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
- " scsi_eh_%d waking"
- " up\n",shost->host_no));
-
- shost->eh_active = 1;
+ SCSI_LOG_ERROR_RECOVERY(1,
+ printk("Error handler scsi_eh_%d waking up\n",
+ shost->host_no));
/*
* We have a host that is failing for some reason. Figure out
@@ -1622,12 +1564,10 @@ int scsi_error_handler(void *data)
* If we fail, we end up taking the thing offline.
*/
if (shost->hostt->eh_strategy_handler)
- rtn = shost->hostt->eh_strategy_handler(shost);
+ shost->hostt->eh_strategy_handler(shost);
else
scsi_unjam_host(shost);
- shost->eh_active = 0;
-
/*
* Note - if the above fails completely, the action is to take
* individual devices offline and flush the queue of any
@@ -1638,15 +1578,10 @@ int scsi_error_handler(void *data)
scsi_restart_operations(shost);
set_current_state(TASK_INTERRUPTIBLE);
}
-
__set_current_state(TASK_RUNNING);
- SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d"
- " exiting\n",shost->host_no));
-
- /*
- * Make sure that nobody tries to wake us up again.
- */
+ SCSI_LOG_ERROR_RECOVERY(1,
+ printk("Error handler scsi_eh_%d exiting\n", shost->host_no));
shost->ehandler = NULL;
return 0;
}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index e40c8b6..ce9d73a 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -254,55 +254,6 @@ void scsi_do_req(struct scsi_request *sreq, const void *cmnd,
}
EXPORT_SYMBOL(scsi_do_req);
-/* This is the end routine we get to if a command was never attached
- * to the request. Simply complete the request without changing
- * rq_status; this will cause a DRIVER_ERROR. */
-static void scsi_wait_req_end_io(struct request *req)
-{
- BUG_ON(!req->waiting);
-
- complete(req->waiting);
-}
-
-void scsi_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer,
- unsigned bufflen, int timeout, int retries)
-{
- DECLARE_COMPLETION(wait);
- int write = (sreq->sr_data_direction == DMA_TO_DEVICE);
- struct request *req;
-
- req = blk_get_request(sreq->sr_device->request_queue, write,
- __GFP_WAIT);
- if (bufflen && blk_rq_map_kern(sreq->sr_device->request_queue, req,
- buffer, bufflen, __GFP_WAIT)) {
- sreq->sr_result = DRIVER_ERROR << 24;
- blk_put_request(req);
- return;
- }
-
- req->flags |= REQ_NOMERGE;
- req->waiting = &wait;
- req->end_io = scsi_wait_req_end_io;
- req->cmd_len = COMMAND_SIZE(((u8 *)cmnd)[0]);
- req->sense = sreq->sr_sense_buffer;
- req->sense_len = 0;
- memcpy(req->cmd, cmnd, req->cmd_len);
- req->timeout = timeout;
- req->flags |= REQ_BLOCK_PC;
- req->rq_disk = NULL;
- blk_insert_request(sreq->sr_device->request_queue, req,
- sreq->sr_data_direction == DMA_TO_DEVICE, NULL);
- wait_for_completion(&wait);
- sreq->sr_request->waiting = NULL;
- sreq->sr_result = req->errors;
- if (req->errors)
- sreq->sr_result |= (DRIVER_ERROR << 24);
-
- blk_put_request(req);
-}
-
-EXPORT_SYMBOL(scsi_wait_req);
-
/**
* scsi_execute - insert request and wait for the result
* @sdev: scsi device
@@ -591,10 +542,17 @@ static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
void scsi_next_command(struct scsi_cmnd *cmd)
{
- struct request_queue *q = cmd->device->request_queue;
+ struct scsi_device *sdev = cmd->device;
+ struct request_queue *q = sdev->request_queue;
+
+ /* need to hold a reference on the device before we let go of the cmd */
+ get_device(&sdev->sdev_gendev);
scsi_put_command(cmd);
scsi_run_queue(q);
+
+ /* ok to remove device now */
+ put_device(&sdev->sdev_gendev);
}
void scsi_run_host_queues(struct Scsi_Host *shost)
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index d05f778..d632d9e 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -22,7 +22,6 @@ struct Scsi_Host;
* Scsi Error Handler Flags
*/
#define SCSI_EH_CANCEL_CMD 0x0001 /* Cancel this cmd */
-#define SCSI_EH_REC_TIMEOUT 0x0002 /* EH retry timed out */
#define SCSI_SENSE_VALID(scmd) \
(((scmd)->sense_buffer[0] & 0x70) == 0x70)
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 7eb3a2d..374853d 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -9,7 +9,7 @@
* global variable (boot or module load time) settings.
*
* A specific LUN is scanned via an INQUIRY command; if the LUN has a
- * device attached, a Scsi_Device is allocated and setup for it.
+ * device attached, a scsi_device is allocated and setup for it.
*
* For every id of every channel on the given host:
*
@@ -17,7 +17,7 @@
* device or storage attached to LUN 0):
*
* If LUN 0 has a device attached, allocate and setup a
- * Scsi_Device for it.
+ * scsi_device for it.
*
* If target is SCSI-3 or up, issue a REPORT LUN, and scan
* all of the LUNs returned by the REPORT LUN; else,
@@ -441,7 +441,7 @@ void scsi_target_reap(struct scsi_target *starget)
*
* If the INQUIRY is successful, zero is returned and the
* INQUIRY data is in @inq_result; the scsi_level and INQUIRY length
- * are copied to the Scsi_Device any flags value is stored in *@bflags.
+ * are copied to the scsi_device any flags value is stored in *@bflags.
**/
static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
int result_len, int *bflags)
@@ -509,8 +509,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
/*
* Get any flags for this device.
*
- * XXX add a bflags to Scsi_Device, and replace the
- * corresponding bit fields in Scsi_Device, so bflags
+ * XXX add a bflags to scsi_device, and replace the
+ * corresponding bit fields in scsi_device, so bflags
* need not be passed as an argument.
*/
*bflags = scsi_get_device_flags(sdev, &inq_result[8],
@@ -592,21 +592,21 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
}
/**
- * scsi_add_lun - allocate and fully initialze a Scsi_Device
- * @sdevscan: holds information to be stored in the new Scsi_Device
- * @sdevnew: store the address of the newly allocated Scsi_Device
+ * scsi_add_lun - allocate and fully initialze a scsi_device
+ * @sdevscan: holds information to be stored in the new scsi_device
+ * @sdevnew: store the address of the newly allocated scsi_device
* @inq_result: holds the result of a previous INQUIRY to the LUN
* @bflags: black/white list flag
*
* Description:
- * Allocate and initialize a Scsi_Device matching sdevscan. Optionally
+ * Allocate and initialize a scsi_device matching sdevscan. Optionally
* set fields based on values in *@bflags. If @sdevnew is not
- * NULL, store the address of the new Scsi_Device in *@sdevnew (needed
+ * NULL, store the address of the new scsi_device in *@sdevnew (needed
* when scanning a particular LUN).
*
* Return:
- * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a Scsi_Device
- * SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized
+ * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
+ * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
**/
static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
{
@@ -674,7 +674,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
*
* The above is vague, as it implies that we could treat 001 and
* 011 the same. Stay compatible with previous code, and create a
- * Scsi_Device for a PQ of 1
+ * scsi_device for a PQ of 1
*
* Don't set the device offline here; rather let the upper
* level drivers eval the PQ to decide whether they should
@@ -784,8 +784,8 @@ static inline void scsi_destroy_sdev(struct scsi_device *sdev)
* scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
* @starget: pointer to target device structure
* @lun: LUN of target device
- * @sdevscan: probe the LUN corresponding to this Scsi_Device
- * @sdevnew: store the value of any new Scsi_Device allocated
+ * @sdevscan: probe the LUN corresponding to this scsi_device
+ * @sdevnew: store the value of any new scsi_device allocated
* @bflagsp: store bflags here if not NULL
*
* Description:
@@ -793,10 +793,10 @@ static inline void scsi_destroy_sdev(struct scsi_device *sdev)
* allocate and set it up by calling scsi_add_lun.
*
* Return:
- * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a Scsi_Device
+ * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
* SCSI_SCAN_TARGET_PRESENT: target responded, but no device is
* attached at the LUN
- * SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized
+ * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
**/
static int scsi_probe_and_add_lun(struct scsi_target *starget,
uint lun, int *bflagsp,
@@ -1046,7 +1046,7 @@ EXPORT_SYMBOL(int_to_scsilun);
/**
* scsi_report_lun_scan - Scan using SCSI REPORT LUN results
- * @sdevscan: scan the host, channel, and id of this Scsi_Device
+ * @sdevscan: scan the host, channel, and id of this scsi_device
*
* Description:
* If @sdevscan is for a SCSI-3 or up device, send a REPORT LUN
@@ -1074,6 +1074,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
struct scsi_sense_hdr sshdr;
struct scsi_device *sdev;
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+ int ret = 0;
/*
* Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set.
@@ -1169,8 +1170,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
/*
* The device probably does not support a REPORT LUN command
*/
- kfree(lun_data);
- return 1;
+ ret = 1;
+ goto out_err;
}
/*
@@ -1238,6 +1239,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
}
}
+ out_err:
kfree(lun_data);
out:
scsi_device_put(sdev);
@@ -1246,7 +1248,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
* the sdev we used didn't appear in the report luns scan
*/
scsi_destroy_sdev(sdev);
- return 0;
+ return ret;
}
struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
@@ -1472,16 +1474,16 @@ void scsi_forget_host(struct Scsi_Host *shost)
/*
* Function: scsi_get_host_dev()
*
- * Purpose: Create a Scsi_Device that points to the host adapter itself.
+ * Purpose: Create a scsi_device that points to the host adapter itself.
*
- * Arguments: SHpnt - Host that needs a Scsi_Device
+ * Arguments: SHpnt - Host that needs a scsi_device
*
* Lock status: None assumed.
*
- * Returns: The Scsi_Device or NULL
+ * Returns: The scsi_device or NULL
*
* Notes:
- * Attach a single Scsi_Device to the Scsi_Host - this should
+ * Attach a single scsi_device to the Scsi_Host - this should
* be made to look like a "pseudo-device" that points to the
* HA itself.
*
@@ -1518,7 +1520,7 @@ EXPORT_SYMBOL(scsi_get_host_dev);
*
* Purpose: Free a scsi_device that points to the host adapter itself.
*
- * Arguments: SHpnt - Host that needs a Scsi_Device
+ * Arguments: SHpnt - Host that needs a scsi_device
*
* Lock status: None assumed.
*
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 72a6550..4634929 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -691,16 +691,19 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
void __scsi_remove_device(struct scsi_device *sdev)
{
+ struct device *dev = &sdev->sdev_gendev;
+
if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
return;
class_device_unregister(&sdev->sdev_classdev);
- device_del(&sdev->sdev_gendev);
+ transport_remove_device(dev);
+ device_del(dev);
scsi_device_set_state(sdev, SDEV_DEL);
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
- transport_unregister_device(&sdev->sdev_gendev);
- put_device(&sdev->sdev_gendev);
+ transport_destroy_device(dev);
+ put_device(dev);
}
/**
diff --git a/drivers/scsi/scsi_typedefs.h b/drivers/scsi/scsi_typedefs.h
index 6c43132..29f038b 100644
--- a/drivers/scsi/scsi_typedefs.h
+++ b/drivers/scsi/scsi_typedefs.h
@@ -1,6 +1,3 @@
-typedef struct scsi_host_template Scsi_Host_Template;
-typedef struct scsi_device Scsi_Device;
typedef struct scsi_cmnd Scsi_Cmnd;
typedef struct scsi_request Scsi_Request;
-typedef struct scsi_pointer Scsi_Pointer;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index bb5b242..8613a13 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -769,20 +769,16 @@ static void sd_end_flush(request_queue_t *q, struct request *flush_rq)
static int sd_prepare_flush(request_queue_t *q, struct request *rq)
{
struct scsi_device *sdev = q->queuedata;
- struct scsi_disk *sdkp = scsi_disk_get_from_dev(&sdev->sdev_gendev);
- int ret = 0;
+ struct scsi_disk *sdkp = dev_get_drvdata(&sdev->sdev_gendev);
- if (sdkp) {
- if (sdkp->WCE) {
- memset(rq->cmd, 0, sizeof(rq->cmd));
- rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
- rq->timeout = SD_TIMEOUT;
- rq->cmd[0] = SYNCHRONIZE_CACHE;
- ret = 1;
- }
- scsi_disk_put(sdkp);
- }
- return ret;
+ if (!sdkp || !sdkp->WCE)
+ return 0;
+
+ memset(rq->cmd, 0, sizeof(rq->cmd));
+ rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
+ rq->timeout = SD_TIMEOUT;
+ rq->cmd[0] = SYNCHRONIZE_CACHE;
+ return 1;
}
static void sd_rescan(struct device *dev)
diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c
index a0cace9..0ff83dd 100644
--- a/drivers/scsi/seagate.c
+++ b/drivers/scsi/seagate.c
@@ -418,7 +418,7 @@ static inline void borken_wait (void)
#define ULOOP( i ) for (clock = i*8;;)
#define TIMEOUT (!(clock--))
-int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
+int __init seagate_st0x_detect (struct scsi_host_template * tpnt)
{
struct Scsi_Host *instance;
int i, j;
@@ -1649,7 +1649,7 @@ static int seagate_st0x_release(struct Scsi_Host *shost)
return 0;
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.detect = seagate_st0x_detect,
.release = seagate_st0x_release,
.info = seagate_st0x_info,
diff --git a/drivers/scsi/seagate.h b/drivers/scsi/seagate.h
index 8889ff1a..fb5f380 100644
--- a/drivers/scsi/seagate.h
+++ b/drivers/scsi/seagate.h
@@ -9,7 +9,7 @@
#ifndef _SEAGATE_H
#define SEAGATE_H
-static int seagate_st0x_detect(Scsi_Host_Template *);
+static int seagate_st0x_detect(struct scsi_host_template *);
static int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int seagate_st0x_abort(Scsi_Cmnd *);
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index f37147f..bf2ceb5 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -217,7 +217,7 @@ static inline void init_hpc_chain(struct hpc_data *hd)
}
static struct Scsi_Host * __init sgiwd93_setup_scsi(
- Scsi_Host_Template *SGIblows, int unit, int irq,
+ struct scsi_host_template *SGIblows, int unit, int irq,
struct hpc3_scsiregs *hregs, unsigned char *wdregs)
{
struct ip22_hostdata *hdata;
@@ -265,7 +265,7 @@ out_unregister:
return NULL;
}
-int __init sgiwd93_detect(Scsi_Host_Template *SGIblows)
+int __init sgiwd93_detect(struct scsi_host_template *SGIblows)
{
int found = 0;
@@ -324,7 +324,7 @@ static int sgiwd93_bus_reset(Scsi_Cmnd *cmd)
* arguments not with pointers. So this is going to blow up beautyfully
* on 64-bit systems with memory outside the compat address spaces.
*/
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "SGIWD93",
.name = "SGI WD93",
.detect = sgiwd93_detect,
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index 7e19589..c041bfd 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -257,7 +257,7 @@
*/
static struct Scsi_Host *first_instance = NULL;
-static Scsi_Host_Template *the_template = NULL;
+static struct scsi_host_template *the_template = NULL;
/* Macros ease life... :-) */
#define SETUP_HOSTDATA(in) \
diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
index e3ea99f..8371734 100644
--- a/drivers/scsi/sun3_scsi.c
+++ b/drivers/scsi/sun3_scsi.c
@@ -185,7 +185,7 @@ static inline void sun3_udc_write(unsigned short val, unsigned char reg)
static struct Scsi_Host *default_instance;
/*
- * Function : int sun3scsi_detect(Scsi_Host_Template * tpnt)
+ * Function : int sun3scsi_detect(struct scsi_host_template * tpnt)
*
* Purpose : initializes mac NCR5380 driver based on the
* command line / compile time port and irq definitions.
@@ -196,7 +196,7 @@ static struct Scsi_Host *default_instance;
*
*/
-int sun3scsi_detect(Scsi_Host_Template * tpnt)
+int sun3scsi_detect(struct scsi_host_template * tpnt)
{
unsigned long ioaddr;
static int called = 0;
@@ -621,7 +621,7 @@ static int sun3scsi_dma_finish(int write_flag)
#include "sun3_NCR5380.c"
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = SUN3_SCSI_NAME,
.detect = sun3scsi_detect,
.release = sun3scsi_release,
diff --git a/drivers/scsi/sun3_scsi.h b/drivers/scsi/sun3_scsi.h
index 155282b..834dab4 100644
--- a/drivers/scsi/sun3_scsi.h
+++ b/drivers/scsi/sun3_scsi.h
@@ -48,7 +48,7 @@
#define IOBASE_SUN3_VMESCSI 0xff200000
static int sun3scsi_abort (Scsi_Cmnd *);
-static int sun3scsi_detect (Scsi_Host_Template *);
+static int sun3scsi_detect (struct scsi_host_template *);
static const char *sun3scsi_info (struct Scsi_Host *);
static int sun3scsi_bus_reset(Scsi_Cmnd *);
static int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
diff --git a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c
index 9acb5dd..008a82a 100644
--- a/drivers/scsi/sun3_scsi_vme.c
+++ b/drivers/scsi/sun3_scsi_vme.c
@@ -127,7 +127,7 @@ static inline void sun3scsi_write(int reg, int value)
static struct Scsi_Host *default_instance;
/*
- * Function : int sun3scsi_detect(Scsi_Host_Template * tpnt)
+ * Function : int sun3scsi_detect(struct scsi_host_template * tpnt)
*
* Purpose : initializes mac NCR5380 driver based on the
* command line / compile time port and irq definitions.
@@ -138,7 +138,7 @@ static struct Scsi_Host *default_instance;
*
*/
-static int sun3scsi_detect(Scsi_Host_Template * tpnt)
+static int sun3scsi_detect(struct scsi_host_template * tpnt)
{
unsigned long ioaddr, irq = 0;
static int called = 0;
@@ -564,7 +564,7 @@ static int sun3scsi_dma_finish(int write_flag)
#include "sun3_NCR5380.c"
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = SUN3_SCSI_NAME,
.detect = sun3scsi_detect,
.release = sun3scsi_release,
diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
index 09d7639..cc990be 100644
--- a/drivers/scsi/sun3x_esp.c
+++ b/drivers/scsi/sun3x_esp.c
@@ -47,7 +47,7 @@ static void dma_advance_sg (Scsi_Cmnd *sp);
/* Detecting ESP chips on the machine. This is the simple and easy
* version.
*/
-int sun3x_esp_detect(Scsi_Host_Template *tpnt)
+int sun3x_esp_detect(struct scsi_host_template *tpnt)
{
struct NCR_ESP *esp;
struct ConfigDev *esp_dev;
@@ -367,7 +367,7 @@ static int sun3x_esp_release(struct Scsi_Host *instance)
}
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "sun3x_esp",
.proc_info = &esp_proc_info,
.name = "Sun ESP 100/100a/200",
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
index 93dc7b6..8640253 100644
--- a/drivers/scsi/sym53c416.c
+++ b/drivers/scsi/sym53c416.c
@@ -633,7 +633,7 @@ static void sym53c416_probe(void)
}
}
-int __init sym53c416_detect(Scsi_Host_Template *tpnt)
+int __init sym53c416_detect(struct scsi_host_template *tpnt)
{
unsigned long flags;
struct Scsi_Host * shpnt = NULL;
@@ -849,7 +849,7 @@ module_param_array(sym53c416_3, uint, NULL, 0);
#endif
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "sym53c416",
.name = "Symbios Logic 53c416",
.detect = sym53c416_detect,
diff --git a/drivers/scsi/sym53c416.h b/drivers/scsi/sym53c416.h
index fd6b120..77860d0 100644
--- a/drivers/scsi/sym53c416.h
+++ b/drivers/scsi/sym53c416.h
@@ -22,7 +22,7 @@
#define SYM53C416_SCSI_ID 7
-static int sym53c416_detect(Scsi_Host_Template *);
+static int sym53c416_detect(struct scsi_host_template *);
static const char *sym53c416_info(struct Scsi_Host *);
static int sym53c416_release(struct Scsi_Host *);
static int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c
index f4b780e..21305fc 100644
--- a/drivers/scsi/t128.c
+++ b/drivers/scsi/t128.c
@@ -183,7 +183,7 @@ void __init t128_setup(char *str, int *ints){
}
/*
- * Function : int t128_detect(Scsi_Host_Template * tpnt)
+ * Function : int t128_detect(struct scsi_host_template * tpnt)
*
* Purpose : detects and initializes T128,T128F, or T228 controllers
* that were autoprobed, overridden on the LILO command line,
@@ -195,7 +195,7 @@ void __init t128_setup(char *str, int *ints){
*
*/
-int __init t128_detect(Scsi_Host_Template * tpnt){
+int __init t128_detect(struct scsi_host_template * tpnt){
static int current_override = 0, current_base = 0;
struct Scsi_Host *instance;
unsigned long base;
@@ -430,7 +430,7 @@ MODULE_LICENSE("GPL");
#include "NCR5380.c"
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = "Trantor T128/T128F/T228",
.detect = t128_detect,
.release = t128_release,
diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h
index 596f3a3..646e840 100644
--- a/drivers/scsi/t128.h
+++ b/drivers/scsi/t128.h
@@ -95,7 +95,7 @@
static int t128_abort(Scsi_Cmnd *);
static int t128_biosparam(struct scsi_device *, struct block_device *,
sector_t, int*);
-static int t128_detect(Scsi_Host_Template *);
+static int t128_detect(struct scsi_host_template *);
static int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int t128_bus_reset(Scsi_Cmnd *);
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index 1ce29ba..33cd90f 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -282,7 +282,7 @@
* clustering is enabled. ENABLE_CLUSTERING provides a performance increase
* up to 50% on sequential access.
*
- * Since the Scsi_Host_Template structure is shared among all 14F and 34F,
+ * Since the struct scsi_host_template structure is shared among all 14F and 34F,
* the last setting of use_clustering is in effect for all of these boards.
*
* Here a sample configuration using two U14F boards:
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
index 486551b..e681681 100644
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -343,7 +343,7 @@ static void log_ultrastor_abort(struct ultrastor_config *config,
}
#endif
-static int ultrastor_14f_detect(Scsi_Host_Template * tpnt)
+static int ultrastor_14f_detect(struct scsi_host_template * tpnt)
{
size_t i;
unsigned char in_byte, version_byte = 0;
@@ -525,7 +525,7 @@ out_release_port:
return FALSE;
}
-static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
+static int ultrastor_24f_detect(struct scsi_host_template * tpnt)
{
int i;
struct Scsi_Host * shpnt = NULL;
@@ -637,7 +637,7 @@ static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
return FALSE;
}
-static int ultrastor_detect(Scsi_Host_Template * tpnt)
+static int ultrastor_detect(struct scsi_host_template * tpnt)
{
tpnt->proc_name = "ultrastor";
return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
@@ -1184,7 +1184,7 @@ static irqreturn_t do_ultrastor_interrupt(int irq, void *dev_id,
MODULE_LICENSE("GPL");
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = "UltraStor 14F/24F/34F",
.detect = ultrastor_detect,
.release = ultrastor_release,
diff --git a/drivers/scsi/ultrastor.h b/drivers/scsi/ultrastor.h
index 0a0f8df..da759a1 100644
--- a/drivers/scsi/ultrastor.h
+++ b/drivers/scsi/ultrastor.h
@@ -13,7 +13,7 @@
#ifndef _ULTRASTOR_H
#define _ULTRASTOR_H
-static int ultrastor_detect(Scsi_Host_Template *);
+static int ultrastor_detect(struct scsi_host_template *);
static const char *ultrastor_info(struct Scsi_Host * shpnt);
static int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int ultrastor_abort(Scsi_Cmnd *);
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 2efb317..67e9afa 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -34,6 +34,7 @@
#include <linux/keyboard.h>
#include <linux/init.h>
#include <linux/pm.h>
+#include <linux/pm_legacy.h>
#include <linux/bitops.h>
#include <linux/delay.h>
@@ -1343,7 +1344,7 @@ static void show_serial_version(void)
printk("MC68328 serial driver version 1.00\n");
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
/* Serial Power management
* The console (currently fixed at line 0) is a special case for power
* management because the kernel is so chatty. The console will be
@@ -1393,7 +1394,7 @@ void startup_console(void)
struct m68k_serial *info = &m68k_soft[0];
startup(info);
}
-#endif
+#endif /* CONFIG_PM_LEGACY */
static struct tty_operations rs_ops = {
@@ -1486,7 +1487,7 @@ rs68328_init(void)
IRQ_FLG_STD,
"M68328_UART", NULL))
panic("Unable to attach 68328 serial interrupt\n");
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
serial_pm[i] = pm_register(PM_SYS_DEV, PM_SYS_COM, serial_pm_callback);
if (serial_pm[i])
serial_pm[i]->data = info;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 9882060..e08510d 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -999,7 +999,10 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
serial_outp(up, UART_MCR, save_mcr);
serial8250_clear_fifos(up);
(void)serial_in(up, UART_RX);
- serial_outp(up, UART_IER, 0);
+ if (up->capabilities & UART_CAP_UUE)
+ serial_outp(up, UART_IER, UART_IER_UUE);
+ else
+ serial_outp(up, UART_IER, 0);
out:
spin_unlock_irqrestore(&up->port.lock, flags);
@@ -2381,9 +2384,9 @@ void serial8250_resume_port(int line)
* list is terminated with a zero flags entry, which means we expect
* all entries to have at least UPF_BOOT_AUTOCONF set.
*/
-static int __devinit serial8250_probe(struct device *dev)
+static int __devinit serial8250_probe(struct platform_device *dev)
{
- struct plat_serial8250_port *p = dev->platform_data;
+ struct plat_serial8250_port *p = dev->dev.platform_data;
struct uart_port port;
int ret, i;
@@ -2399,12 +2402,12 @@ static int __devinit serial8250_probe(struct device *dev)
port.flags = p->flags;
port.mapbase = p->mapbase;
port.hub6 = p->hub6;
- port.dev = dev;
+ port.dev = &dev->dev;
if (share_irqs)
port.flags |= UPF_SHARE_IRQ;
ret = serial8250_register_port(&port);
if (ret < 0) {
- dev_err(dev, "unable to register port at index %d "
+ dev_err(&dev->dev, "unable to register port at index %d "
"(IO%lx MEM%lx IRQ%d): %d\n", i,
p->iobase, p->mapbase, p->irq, ret);
}
@@ -2415,54 +2418,55 @@ static int __devinit serial8250_probe(struct device *dev)
/*
* Remove serial ports registered against a platform device.
*/
-static int __devexit serial8250_remove(struct device *dev)
+static int __devexit serial8250_remove(struct platform_device *dev)
{
int i;
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
- if (up->port.dev == dev)
+ if (up->port.dev == &dev->dev)
serial8250_unregister_port(i);
}
return 0;
}
-static int serial8250_suspend(struct device *dev, pm_message_t state)
+static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
{
int i;
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
- if (up->port.type != PORT_UNKNOWN && up->port.dev == dev)
+ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
uart_suspend_port(&serial8250_reg, &up->port);
}
return 0;
}
-static int serial8250_resume(struct device *dev)
+static int serial8250_resume(struct platform_device *dev)
{
int i;
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
- if (up->port.type != PORT_UNKNOWN && up->port.dev == dev)
+ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
uart_resume_port(&serial8250_reg, &up->port);
}
return 0;
}
-static struct device_driver serial8250_isa_driver = {
- .name = "serial8250",
- .bus = &platform_bus_type,
+static struct platform_driver serial8250_isa_driver = {
.probe = serial8250_probe,
.remove = __devexit_p(serial8250_remove),
.suspend = serial8250_suspend,
.resume = serial8250_resume,
+ .driver = {
+ .name = "serial8250",
+ },
};
/*
@@ -2608,7 +2612,7 @@ static int __init serial8250_init(void)
serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
- ret = driver_register(&serial8250_isa_driver);
+ ret = platform_driver_register(&serial8250_isa_driver);
if (ret == 0)
goto out;
@@ -2630,7 +2634,7 @@ static void __exit serial8250_exit(void)
*/
serial8250_isa_devs = NULL;
- driver_unregister(&serial8250_isa_driver);
+ platform_driver_unregister(&serial8250_isa_driver);
platform_device_unregister(isa_dev);
uart_unregister_driver(&serial8250_reg);
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 5d8660a..b79ed06 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -323,6 +323,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "USR9180", 0 },
/* U.S. Robotics 56K Voice INT PnP*/
{ "USR9190", 0 },
+ /* HP Compaq Tablet PC tc1100 Wacom tablet */
+ { "WACF005", 0 },
/* Rockwell's (PORALiNK) 33600 INT PNP */
{ "WCI0003", 0 },
/* Unkown PnP modems */
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index ff36f0c..ad47c1b 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -507,7 +507,7 @@ config SERIAL_SUNSU_CONSOLE
config SERIAL_MUX
tristate "Serial MUX support"
- depends on PARISC
+ depends on GSC
select SERIAL_CORE
default y
---help---
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 25825f2..987d22b 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -7,7 +7,7 @@
* Based on ppc8xx.c by Thomas Gleixner
* Based on drivers/serial/amba.c by Russell King
*
- * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2)
+ * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
* Pantelis Antoniou (panto@intracom.gr) (CPM1)
*
* Copyright (C) 2004 Freescale Semiconductor, Inc.
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index 4b0786e..d789ee5 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -3,7 +3,7 @@
*
* Driver for CPM (SCC/SMC) serial ports; CPM1 definitions
*
- * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2)
+ * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
* Pantelis Antoniou (panto@intracom.gr) (CPM1)
*
* Copyright (C) 2004 Freescale Semiconductor, Inc.
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index 15ad58d..fd9e53e 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -3,7 +3,7 @@
*
* Driver for CPM (SCC/SMC) serial ports; CPM2 definitions
*
- * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2)
+ * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
* Pantelis Antoniou (panto@intracom.gr) (CPM1)
*
* Copyright (C) 2004 Freescale Semiconductor, Inc.
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index e63b9df..4d8516d 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -1,9 +1,9 @@
/*
- * dz.c: Serial port driver for DECStations equiped
+ * dz.c: Serial port driver for DECStations equiped
* with the DZ chipset.
*
- * Copyright (C) 1998 Olivier A. D. Lebaillif
- *
+ * Copyright (C) 1998 Olivier A. D. Lebaillif
+ *
* Email: olivier.lebaillif@ifrsys.com
*
* [31-AUG-98] triemer
@@ -11,14 +11,14 @@
* removed base_addr code - moving address assignment to setup.c
* Changed name of dz_init to rs_init to be consistent with tc code
* [13-NOV-98] triemer fixed code to receive characters
- * after patches by harald to irq code.
+ * after patches by harald to irq code.
* [09-JAN-99] triemer minor fix for schedule - due to removal of timeout
* field from "current" - somewhere between 2.1.121 and 2.1.131
Qua Jun 27 15:02:26 BRT 2001
* [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups
- *
- * Parts (C) 1999 David Airlie, airlied@linux.ie
- * [07-SEP-99] Bugfixes
+ *
+ * Parts (C) 1999 David Airlie, airlied@linux.ie
+ * [07-SEP-99] Bugfixes
*
* [06-Jan-2002] Russell King <rmk@arm.linux.org.uk>
* Converted to new serial core
@@ -64,7 +64,7 @@ static struct dz_port dz_ports[DZ_NB_PORT];
#ifdef DEBUG_DZ
/*
- * debugging code to send out chars via prom
+ * debugging code to send out chars via prom
*/
static void debug_console(const char *s, int count)
{
@@ -82,7 +82,7 @@ static void debug_console(const char *s, int count)
* ------------------------------------------------------------
* dz_in () and dz_out ()
*
- * These routines are used to access the registers of the DZ
+ * These routines are used to access the registers of the DZ
* chip, hiding relocation differences between implementation.
* ------------------------------------------------------------
*/
@@ -106,8 +106,8 @@ static inline void dz_out(struct dz_port *dport, unsigned offset,
* ------------------------------------------------------------
* rs_stop () and rs_start ()
*
- * These routines are called before setting or resetting
- * tty->stopped. They enable or disable transmitter interrupts,
+ * These routines are called before setting or resetting
+ * tty->stopped. They enable or disable transmitter interrupts,
* as necessary.
* ------------------------------------------------------------
*/
@@ -156,17 +156,17 @@ static void dz_enable_ms(struct uart_port *port)
/*
* ------------------------------------------------------------
- * Here starts the interrupt handling routines. All of the
- * following subroutines are declared as inline and are folded
- * into dz_interrupt. They were separated out for readability's
- * sake.
+ * Here starts the interrupt handling routines. All of the
+ * following subroutines are declared as inline and are folded
+ * into dz_interrupt. They were separated out for readability's
+ * sake.
*
* Note: rs_interrupt() is a "fast" interrupt, which means that it
* runs with interrupts turned off. People who may want to modify
* rs_interrupt() should try to keep the interrupt handler as fast as
* possible. After you are done making modifications, it is not a bad
* idea to do:
- *
+ *
* make drivers/serial/dz.s
*
* and look at the resulting assemble code in dz.s.
@@ -403,7 +403,7 @@ static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
* startup ()
*
* various initialization tasks
- * -------------------------------------------------------------------
+ * -------------------------------------------------------------------
*/
static int dz_startup(struct uart_port *uport)
{
@@ -430,13 +430,13 @@ static int dz_startup(struct uart_port *uport)
return 0;
}
-/*
+/*
* -------------------------------------------------------------------
* shutdown ()
*
* This routine will shutdown a serial port; interrupts are disabled, and
* DTR is dropped if the hangup on close termio flag is on.
- * -------------------------------------------------------------------
+ * -------------------------------------------------------------------
*/
static void dz_shutdown(struct uart_port *uport)
{
@@ -451,7 +451,7 @@ static void dz_shutdown(struct uart_port *uport)
* release the bus after transmitting. This must be done when
* the transmit shift register is empty, not be done when the
* transmit holding register is empty. This functionality
- * allows an RS485 driver to be written in user space.
+ * allows an RS485 driver to be written in user space.
*/
static unsigned int dz_tx_empty(struct uart_port *uport)
{
@@ -645,9 +645,9 @@ static void __init dz_init_ports(void)
if (mips_machtype == MACH_DS23100 ||
mips_machtype == MACH_DS5100)
- base = (unsigned long) KN01_DZ11_BASE;
+ base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_DZ11);
else
- base = (unsigned long) KN02_DZ11_BASE;
+ base = CKSEG1ADDR(KN02_SLOT_BASE + KN02_DZ11);
for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
spin_lock_init(&dport->port.lock);
@@ -695,13 +695,13 @@ static void dz_console_put_char(struct dz_port *dport, unsigned char ch)
spin_unlock_irqrestore(&dport->port.lock, flags);
}
-/*
+/*
* -------------------------------------------------------------------
* dz_console_print ()
*
* dz_console_print is registered for printk.
* The console must be locked when we get here.
- * -------------------------------------------------------------------
+ * -------------------------------------------------------------------
*/
static void dz_console_print(struct console *cons,
const char *str,
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 4a54ff5..355cd93 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -921,9 +921,9 @@ static struct uart_driver imx_reg = {
.cons = IMX_CONSOLE,
};
-static int serial_imx_suspend(struct device *_dev, pm_message_t state)
+static int serial_imx_suspend(struct platform_device *dev, pm_message_t state)
{
- struct imx_port *sport = dev_get_drvdata(_dev);
+ struct imx_port *sport = platform_get_drvdata(dev);
if (sport)
uart_suspend_port(&imx_reg, &sport->port);
@@ -931,9 +931,9 @@ static int serial_imx_suspend(struct device *_dev, pm_message_t state)
return 0;
}
-static int serial_imx_resume(struct device *_dev)
+static int serial_imx_resume(struct platform_device *dev)
{
- struct imx_port *sport = dev_get_drvdata(_dev);
+ struct imx_port *sport = platform_get_drvdata(dev);
if (sport)
uart_resume_port(&imx_reg, &sport->port);
@@ -941,21 +941,19 @@ static int serial_imx_resume(struct device *_dev)
return 0;
}
-static int serial_imx_probe(struct device *_dev)
+static int serial_imx_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
-
- imx_ports[dev->id].port.dev = _dev;
+ imx_ports[dev->id].port.dev = &dev->dev;
uart_add_one_port(&imx_reg, &imx_ports[dev->id].port);
- dev_set_drvdata(_dev, &imx_ports[dev->id]);
+ platform_set_drvdata(dev, &imx_ports[dev->id]);
return 0;
}
-static int serial_imx_remove(struct device *_dev)
+static int serial_imx_remove(struct platform_device *dev)
{
- struct imx_port *sport = dev_get_drvdata(_dev);
+ struct imx_port *sport = platform_get_drvdata(dev);
- dev_set_drvdata(_dev, NULL);
+ platform_set_drvdata(dev, NULL);
if (sport)
uart_remove_one_port(&imx_reg, &sport->port);
@@ -963,14 +961,15 @@ static int serial_imx_remove(struct device *_dev)
return 0;
}
-static struct device_driver serial_imx_driver = {
- .name = "imx-uart",
- .bus = &platform_bus_type,
+static struct platform_driver serial_imx_driver = {
.probe = serial_imx_probe,
.remove = serial_imx_remove,
.suspend = serial_imx_suspend,
.resume = serial_imx_resume,
+ .driver = {
+ .name = "imx-uart",
+ },
};
static int __init imx_serial_init(void)
@@ -985,7 +984,7 @@ static int __init imx_serial_init(void)
if (ret)
return ret;
- ret = driver_register(&serial_imx_driver);
+ ret = platform_driver_register(&serial_imx_driver);
if (ret != 0)
uart_unregister_driver(&imx_reg);
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 0dd08a0..b8727d9 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -717,16 +717,15 @@ static struct uart_driver mpc52xx_uart_driver = {
/* ======================================================================== */
static int __devinit
-mpc52xx_uart_probe(struct device *dev)
+mpc52xx_uart_probe(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct resource *res = pdev->resource;
+ struct resource *res = dev->resource;
struct uart_port *port = NULL;
int i, idx, ret;
/* Check validity & presence */
- idx = pdev->id;
+ idx = dev->id;
if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM)
return -EINVAL;
@@ -749,7 +748,7 @@ mpc52xx_uart_probe(struct device *dev)
port->ops = &mpc52xx_uart_ops;
/* Search for IRQ and mapbase */
- for (i=0 ; i<pdev->num_resources ; i++, res++) {
+ for (i=0 ; i<dev->num_resources ; i++, res++) {
if (res->flags & IORESOURCE_MEM)
port->mapbase = res->start;
else if (res->flags & IORESOURCE_IRQ)
@@ -761,17 +760,17 @@ mpc52xx_uart_probe(struct device *dev)
/* Add the port to the uart sub-system */
ret = uart_add_one_port(&mpc52xx_uart_driver, port);
if (!ret)
- dev_set_drvdata(dev, (void*)port);
+ platform_set_drvdata(dev, (void*)port);
return ret;
}
static int
-mpc52xx_uart_remove(struct device *dev)
+mpc52xx_uart_remove(struct platform_device *dev)
{
- struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
+ struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
if (port)
uart_remove_one_port(&mpc52xx_uart_driver, port);
@@ -781,9 +780,9 @@ mpc52xx_uart_remove(struct device *dev)
#ifdef CONFIG_PM
static int
-mpc52xx_uart_suspend(struct device *dev, pm_message_t state)
+mpc52xx_uart_suspend(struct platform_device *dev, pm_message_t state)
{
- struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
+ struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
if (sport)
uart_suspend_port(&mpc52xx_uart_driver, port);
@@ -792,9 +791,9 @@ mpc52xx_uart_suspend(struct device *dev, pm_message_t state)
}
static int
-mpc52xx_uart_resume(struct device *dev)
+mpc52xx_uart_resume(struct platform_device *dev)
{
- struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
+ struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
if (port)
uart_resume_port(&mpc52xx_uart_driver, port);
@@ -803,15 +802,16 @@ mpc52xx_uart_resume(struct device *dev)
}
#endif
-static struct device_driver mpc52xx_uart_platform_driver = {
- .name = "mpc52xx-psc",
- .bus = &platform_bus_type,
+static struct platform_driver mpc52xx_uart_platform_driver = {
.probe = mpc52xx_uart_probe,
.remove = mpc52xx_uart_remove,
#ifdef CONFIG_PM
.suspend = mpc52xx_uart_suspend,
.resume = mpc52xx_uart_resume,
#endif
+ .driver = {
+ .name = "mpc52xx-psc",
+ },
};
@@ -828,7 +828,7 @@ mpc52xx_uart_init(void)
ret = uart_register_driver(&mpc52xx_uart_driver);
if (ret == 0) {
- ret = driver_register(&mpc52xx_uart_platform_driver);
+ ret = platform_driver_register(&mpc52xx_uart_platform_driver);
if (ret)
uart_unregister_driver(&mpc52xx_uart_driver);
}
@@ -839,7 +839,7 @@ mpc52xx_uart_init(void)
static void __exit
mpc52xx_uart_exit(void)
{
- driver_unregister(&mpc52xx_uart_platform_driver);
+ platform_driver_unregister(&mpc52xx_uart_platform_driver);
uart_unregister_driver(&mpc52xx_uart_driver);
}
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index ba8838b..8f83e40 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -1551,15 +1551,14 @@ mpsc_shared_unmap_regs(void)
}
static int
-mpsc_shared_drv_probe(struct device *dev)
+mpsc_shared_drv_probe(struct platform_device *dev)
{
- struct platform_device *pd = to_platform_device(dev);
struct mpsc_shared_pdata *pdata;
int rc = -ENODEV;
- if (pd->id == 0) {
- if (!(rc = mpsc_shared_map_regs(pd))) {
- pdata = (struct mpsc_shared_pdata *)dev->platform_data;
+ if (dev->id == 0) {
+ if (!(rc = mpsc_shared_map_regs(dev))) {
+ pdata = (struct mpsc_shared_pdata *)dev->dev.platform_data;
mpsc_shared_regs.MPSC_MRR_m = pdata->mrr_val;
mpsc_shared_regs.MPSC_RCRR_m= pdata->rcrr_val;
@@ -1577,12 +1576,11 @@ mpsc_shared_drv_probe(struct device *dev)
}
static int
-mpsc_shared_drv_remove(struct device *dev)
+mpsc_shared_drv_remove(struct platform_device *dev)
{
- struct platform_device *pd = to_platform_device(dev);
int rc = -ENODEV;
- if (pd->id == 0) {
+ if (dev->id == 0) {
mpsc_shared_unmap_regs();
mpsc_shared_regs.MPSC_MRR_m = 0;
mpsc_shared_regs.MPSC_RCRR_m = 0;
@@ -1595,11 +1593,12 @@ mpsc_shared_drv_remove(struct device *dev)
return rc;
}
-static struct device_driver mpsc_shared_driver = {
- .name = MPSC_SHARED_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver mpsc_shared_driver = {
.probe = mpsc_shared_drv_probe,
.remove = mpsc_shared_drv_remove,
+ .driver = {
+ .name = MPSC_SHARED_NAME,
+ },
};
/*
@@ -1732,19 +1731,18 @@ mpsc_drv_get_platform_data(struct mpsc_port_info *pi,
}
static int
-mpsc_drv_probe(struct device *dev)
+mpsc_drv_probe(struct platform_device *dev)
{
- struct platform_device *pd = to_platform_device(dev);
struct mpsc_port_info *pi;
int rc = -ENODEV;
- pr_debug("mpsc_drv_probe: Adding MPSC %d\n", pd->id);
+ pr_debug("mpsc_drv_probe: Adding MPSC %d\n", dev->id);
- if (pd->id < MPSC_NUM_CTLRS) {
- pi = &mpsc_ports[pd->id];
+ if (dev->id < MPSC_NUM_CTLRS) {
+ pi = &mpsc_ports[dev->id];
- if (!(rc = mpsc_drv_map_regs(pi, pd))) {
- mpsc_drv_get_platform_data(pi, pd, pd->id);
+ if (!(rc = mpsc_drv_map_regs(pi, dev))) {
+ mpsc_drv_get_platform_data(pi, dev, dev->id);
if (!(rc = mpsc_make_ready(pi)))
if (!(rc = uart_add_one_port(&mpsc_reg,
@@ -1764,27 +1762,26 @@ mpsc_drv_probe(struct device *dev)
}
static int
-mpsc_drv_remove(struct device *dev)
+mpsc_drv_remove(struct platform_device *dev)
{
- struct platform_device *pd = to_platform_device(dev);
+ pr_debug("mpsc_drv_exit: Removing MPSC %d\n", dev->id);
- pr_debug("mpsc_drv_exit: Removing MPSC %d\n", pd->id);
-
- if (pd->id < MPSC_NUM_CTLRS) {
- uart_remove_one_port(&mpsc_reg, &mpsc_ports[pd->id].port);
- mpsc_release_port((struct uart_port *)&mpsc_ports[pd->id].port);
- mpsc_drv_unmap_regs(&mpsc_ports[pd->id]);
+ if (dev->id < MPSC_NUM_CTLRS) {
+ uart_remove_one_port(&mpsc_reg, &mpsc_ports[dev->id].port);
+ mpsc_release_port((struct uart_port *)&mpsc_ports[dev->id].port);
+ mpsc_drv_unmap_regs(&mpsc_ports[dev->id]);
return 0;
}
else
return -ENODEV;
}
-static struct device_driver mpsc_driver = {
- .name = MPSC_CTLR_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver mpsc_driver = {
.probe = mpsc_drv_probe,
.remove = mpsc_drv_remove,
+ .driver = {
+ .name = MPSC_CTLR_NAME,
+ },
};
static int __init
@@ -1798,9 +1795,9 @@ mpsc_drv_init(void)
memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
if (!(rc = uart_register_driver(&mpsc_reg))) {
- if (!(rc = driver_register(&mpsc_shared_driver))) {
- if ((rc = driver_register(&mpsc_driver))) {
- driver_unregister(&mpsc_shared_driver);
+ if (!(rc = platform_driver_register(&mpsc_shared_driver))) {
+ if ((rc = platform_driver_register(&mpsc_driver))) {
+ platform_driver_unregister(&mpsc_shared_driver);
uart_unregister_driver(&mpsc_reg);
}
}
@@ -1815,8 +1812,8 @@ mpsc_drv_init(void)
static void __exit
mpsc_drv_exit(void)
{
- driver_unregister(&mpsc_driver);
- driver_unregister(&mpsc_shared_driver);
+ platform_driver_unregister(&mpsc_driver);
+ platform_driver_unregister(&mpsc_shared_driver);
uart_unregister_driver(&mpsc_reg);
memset(mpsc_ports, 0, sizeof(mpsc_ports));
memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 660bae5..7633132 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -65,8 +65,8 @@ static struct uart_driver mux_driver = {
static struct timer_list mux_timer;
-#define UART_PUT_CHAR(p, c) __raw_writel((c), (unsigned long)(p)->membase + IO_DATA_REG_OFFSET)
-#define UART_GET_FIFO_CNT(p) __raw_readl((unsigned long)(p)->membase + IO_DCOUNT_REG_OFFSET)
+#define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET)
+#define UART_GET_FIFO_CNT(p) __raw_readl((p)->membase + IO_DCOUNT_REG_OFFSET)
#define GET_MUX_PORTS(iodc_data) ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8
/**
@@ -79,10 +79,7 @@ static struct timer_list mux_timer;
*/
static unsigned int mux_tx_empty(struct uart_port *port)
{
- unsigned int cnt = __raw_readl((unsigned long)port->membase
- + IO_DCOUNT_REG_OFFSET);
-
- return cnt ? 0 : TIOCSER_TEMT;
+ return UART_GET_FIFO_CNT(port) ? 0 : TIOCSER_TEMT;
}
/**
@@ -218,8 +215,7 @@ static void mux_read(struct uart_port *port)
__u32 start_count = port->icount.rx;
while(1) {
- data = __raw_readl((unsigned long)port->membase
- + IO_DATA_REG_OFFSET);
+ data = __raw_readl(port->membase + IO_DATA_REG_OFFSET);
if (MUX_STATUS(data))
continue;
@@ -481,6 +477,13 @@ static int __init mux_probe(struct parisc_device *dev)
port->ops = &mux_pops;
port->flags = UPF_BOOT_AUTOCONF;
port->line = port_cnt;
+
+ /* The port->timeout needs to match what is present in
+ * uart_wait_until_sent in serial_core.c. Otherwise
+ * the time spent in msleep_interruptable will be very
+ * long, causing the appearance of a console hang.
+ */
+ port->timeout = HZ / 50;
spin_lock_init(&port->lock);
status = uart_add_one_port(&mux_driver, port);
BUG_ON(status);
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 16b2f94..ff5e630 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -805,9 +805,9 @@ static struct uart_driver serial_pxa_reg = {
.cons = PXA_CONSOLE,
};
-static int serial_pxa_suspend(struct device *_dev, pm_message_t state)
+static int serial_pxa_suspend(struct platform_device *dev, pm_message_t state)
{
- struct uart_pxa_port *sport = dev_get_drvdata(_dev);
+ struct uart_pxa_port *sport = platform_get_drvdata(dev);
if (sport)
uart_suspend_port(&serial_pxa_reg, &sport->port);
@@ -815,9 +815,9 @@ static int serial_pxa_suspend(struct device *_dev, pm_message_t state)
return 0;
}
-static int serial_pxa_resume(struct device *_dev)
+static int serial_pxa_resume(struct platform_device *dev)
{
- struct uart_pxa_port *sport = dev_get_drvdata(_dev);
+ struct uart_pxa_port *sport = platform_get_drvdata(dev);
if (sport)
uart_resume_port(&serial_pxa_reg, &sport->port);
@@ -825,21 +825,19 @@ static int serial_pxa_resume(struct device *_dev)
return 0;
}
-static int serial_pxa_probe(struct device *_dev)
+static int serial_pxa_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
-
- serial_pxa_ports[dev->id].port.dev = _dev;
+ serial_pxa_ports[dev->id].port.dev = &dev->dev;
uart_add_one_port(&serial_pxa_reg, &serial_pxa_ports[dev->id].port);
- dev_set_drvdata(_dev, &serial_pxa_ports[dev->id]);
+ platform_set_drvdata(dev, &serial_pxa_ports[dev->id]);
return 0;
}
-static int serial_pxa_remove(struct device *_dev)
+static int serial_pxa_remove(struct platform_device *dev)
{
- struct uart_pxa_port *sport = dev_get_drvdata(_dev);
+ struct uart_pxa_port *sport = platform_get_drvdata(dev);
- dev_set_drvdata(_dev, NULL);
+ platform_set_drvdata(dev, NULL);
if (sport)
uart_remove_one_port(&serial_pxa_reg, &sport->port);
@@ -847,14 +845,15 @@ static int serial_pxa_remove(struct device *_dev)
return 0;
}
-static struct device_driver serial_pxa_driver = {
- .name = "pxa2xx-uart",
- .bus = &platform_bus_type,
+static struct platform_driver serial_pxa_driver = {
.probe = serial_pxa_probe,
.remove = serial_pxa_remove,
.suspend = serial_pxa_suspend,
.resume = serial_pxa_resume,
+ .driver = {
+ .name = "pxa2xx-uart",
+ },
};
int __init serial_pxa_init(void)
@@ -865,7 +864,7 @@ int __init serial_pxa_init(void)
if (ret != 0)
return ret;
- ret = driver_register(&serial_pxa_driver);
+ ret = platform_driver_register(&serial_pxa_driver);
if (ret != 0)
uart_unregister_driver(&serial_pxa_reg);
@@ -874,7 +873,7 @@ int __init serial_pxa_init(void)
void __exit serial_pxa_exit(void)
{
- driver_unregister(&serial_pxa_driver);
+ platform_driver_unregister(&serial_pxa_driver);
uart_unregister_driver(&serial_pxa_reg);
}
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 0367923..47681c4 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -1092,14 +1092,13 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
static int probe_index = 0;
-static int s3c24xx_serial_probe(struct device *_dev,
+static int s3c24xx_serial_probe(struct platform_device *dev,
struct s3c24xx_uart_info *info)
{
struct s3c24xx_uart_port *ourport;
- struct platform_device *dev = to_platform_device(_dev);
int ret;
- dbg("s3c24xx_serial_probe(%p, %p) %d\n", _dev, info, probe_index);
+ dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index);
ourport = &s3c24xx_serial_ports[probe_index];
probe_index++;
@@ -1112,7 +1111,7 @@ static int s3c24xx_serial_probe(struct device *_dev,
dbg("%s: adding port\n", __FUNCTION__);
uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
- dev_set_drvdata(_dev, &ourport->port);
+ platform_set_drvdata(dev, &ourport->port);
return 0;
@@ -1120,9 +1119,9 @@ static int s3c24xx_serial_probe(struct device *_dev,
return ret;
}
-static int s3c24xx_serial_remove(struct device *_dev)
+static int s3c24xx_serial_remove(struct platform_device *dev)
{
- struct uart_port *port = s3c24xx_dev_to_port(_dev);
+ struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
if (port)
uart_remove_one_port(&s3c24xx_uart_drv, port);
@@ -1134,9 +1133,9 @@ static int s3c24xx_serial_remove(struct device *_dev)
#ifdef CONFIG_PM
-static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state)
+static int s3c24xx_serial_suspend(struct platform_device *dev, pm_message_t state)
{
- struct uart_port *port = s3c24xx_dev_to_port(dev);
+ struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
if (port)
uart_suspend_port(&s3c24xx_uart_drv, port);
@@ -1144,9 +1143,9 @@ static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int s3c24xx_serial_resume(struct device *dev)
+static int s3c24xx_serial_resume(struct platform_device *dev)
{
- struct uart_port *port = s3c24xx_dev_to_port(dev);
+ struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
struct s3c24xx_uart_port *ourport = to_ourport(port);
if (port) {
@@ -1165,11 +1164,11 @@ static int s3c24xx_serial_resume(struct device *dev)
#define s3c24xx_serial_resume NULL
#endif
-static int s3c24xx_serial_init(struct device_driver *drv,
+static int s3c24xx_serial_init(struct platform_driver *drv,
struct s3c24xx_uart_info *info)
{
dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
- return driver_register(drv);
+ return platform_driver_register(drv);
}
@@ -1228,19 +1227,20 @@ static struct s3c24xx_uart_info s3c2400_uart_inf = {
.reset_port = s3c2400_serial_resetport,
};
-static int s3c2400_serial_probe(struct device *dev)
+static int s3c2400_serial_probe(struct platform_device *dev)
{
return s3c24xx_serial_probe(dev, &s3c2400_uart_inf);
}
-static struct device_driver s3c2400_serial_drv = {
- .name = "s3c2400-uart",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver s3c2400_serial_drv = {
.probe = s3c2400_serial_probe,
.remove = s3c24xx_serial_remove,
.suspend = s3c24xx_serial_suspend,
.resume = s3c24xx_serial_resume,
+ .driver = {
+ .name = "s3c2400-uart",
+ .owner = THIS_MODULE,
+ },
};
static inline int s3c2400_serial_init(void)
@@ -1250,7 +1250,7 @@ static inline int s3c2400_serial_init(void)
static inline void s3c2400_serial_exit(void)
{
- driver_unregister(&s3c2400_serial_drv);
+ platform_driver_unregister(&s3c2400_serial_drv);
}
#define s3c2400_uart_inf_at &s3c2400_uart_inf
@@ -1332,19 +1332,20 @@ static struct s3c24xx_uart_info s3c2410_uart_inf = {
/* device management */
-static int s3c2410_serial_probe(struct device *dev)
+static int s3c2410_serial_probe(struct platform_device *dev)
{
return s3c24xx_serial_probe(dev, &s3c2410_uart_inf);
}
-static struct device_driver s3c2410_serial_drv = {
- .name = "s3c2410-uart",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver s3c2410_serial_drv = {
.probe = s3c2410_serial_probe,
.remove = s3c24xx_serial_remove,
.suspend = s3c24xx_serial_suspend,
.resume = s3c24xx_serial_resume,
+ .driver = {
+ .name = "s3c2410-uart",
+ .owner = THIS_MODULE,
+ },
};
static inline int s3c2410_serial_init(void)
@@ -1354,7 +1355,7 @@ static inline int s3c2410_serial_init(void)
static inline void s3c2410_serial_exit(void)
{
- driver_unregister(&s3c2410_serial_drv);
+ platform_driver_unregister(&s3c2410_serial_drv);
}
#define s3c2410_uart_inf_at &s3c2410_uart_inf
@@ -1493,20 +1494,21 @@ static struct s3c24xx_uart_info s3c2440_uart_inf = {
/* device management */
-static int s3c2440_serial_probe(struct device *dev)
+static int s3c2440_serial_probe(struct platform_device *dev)
{
dbg("s3c2440_serial_probe: dev=%p\n", dev);
return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
}
-static struct device_driver s3c2440_serial_drv = {
- .name = "s3c2440-uart",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver s3c2440_serial_drv = {
.probe = s3c2440_serial_probe,
.remove = s3c24xx_serial_remove,
.suspend = s3c24xx_serial_suspend,
.resume = s3c24xx_serial_resume,
+ .driver = {
+ .name = "s3c2440-uart",
+ .owner = THIS_MODULE,
+ },
};
@@ -1517,7 +1519,7 @@ static inline int s3c2440_serial_init(void)
static inline void s3c2440_serial_exit(void)
{
- driver_unregister(&s3c2440_serial_drv);
+ platform_driver_unregister(&s3c2440_serial_drv);
}
#define s3c2440_uart_inf_at &s3c2440_uart_inf
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index ed618cc..0e3daf6 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -156,7 +156,7 @@ static void sa1100_stop_tx(struct uart_port *port)
}
/*
- * interrupts may not be disabled on entry
+ * port locked and interrupts disabled
*/
static void sa1100_start_tx(struct uart_port *port)
{
@@ -164,11 +164,9 @@ static void sa1100_start_tx(struct uart_port *port)
unsigned long flags;
u32 utcr3;
- spin_lock_irqsave(&sport->port.lock, flags);
utcr3 = UART_GET_UTCR3(sport);
sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS);
UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE);
- spin_unlock_irqrestore(&sport->port.lock, flags);
}
/*
@@ -834,9 +832,9 @@ static struct uart_driver sa1100_reg = {
.cons = SA1100_CONSOLE,
};
-static int sa1100_serial_suspend(struct device *_dev, pm_message_t state)
+static int sa1100_serial_suspend(struct platform_device *dev, pm_message_t state)
{
- struct sa1100_port *sport = dev_get_drvdata(_dev);
+ struct sa1100_port *sport = platform_get_drvdata(dev);
if (sport)
uart_suspend_port(&sa1100_reg, &sport->port);
@@ -844,9 +842,9 @@ static int sa1100_serial_suspend(struct device *_dev, pm_message_t state)
return 0;
}
-static int sa1100_serial_resume(struct device *_dev)
+static int sa1100_serial_resume(struct platform_device *dev)
{
- struct sa1100_port *sport = dev_get_drvdata(_dev);
+ struct sa1100_port *sport = platform_get_drvdata(dev);
if (sport)
uart_resume_port(&sa1100_reg, &sport->port);
@@ -854,9 +852,8 @@ static int sa1100_serial_resume(struct device *_dev)
return 0;
}
-static int sa1100_serial_probe(struct device *_dev)
+static int sa1100_serial_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
struct resource *res = dev->resource;
int i;
@@ -869,9 +866,9 @@ static int sa1100_serial_probe(struct device *_dev)
if (sa1100_ports[i].port.mapbase != res->start)
continue;
- sa1100_ports[i].port.dev = _dev;
+ sa1100_ports[i].port.dev = &dev->dev;
uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port);
- dev_set_drvdata(_dev, &sa1100_ports[i]);
+ platform_set_drvdata(dev, &sa1100_ports[i]);
break;
}
}
@@ -879,11 +876,11 @@ static int sa1100_serial_probe(struct device *_dev)
return 0;
}
-static int sa1100_serial_remove(struct device *_dev)
+static int sa1100_serial_remove(struct platform_device *pdev)
{
- struct sa1100_port *sport = dev_get_drvdata(_dev);
+ struct sa1100_port *sport = platform_get_drvdata(pdev);
- dev_set_drvdata(_dev, NULL);
+ platform_set_drvdata(pdev, NULL);
if (sport)
uart_remove_one_port(&sa1100_reg, &sport->port);
@@ -891,13 +888,14 @@ static int sa1100_serial_remove(struct device *_dev)
return 0;
}
-static struct device_driver sa11x0_serial_driver = {
- .name = "sa11x0-uart",
- .bus = &platform_bus_type,
+static struct platform_driver sa11x0_serial_driver = {
.probe = sa1100_serial_probe,
.remove = sa1100_serial_remove,
.suspend = sa1100_serial_suspend,
.resume = sa1100_serial_resume,
+ .driver = {
+ .name = "sa11x0-uart",
+ },
};
static int __init sa1100_serial_init(void)
@@ -910,7 +908,7 @@ static int __init sa1100_serial_init(void)
ret = uart_register_driver(&sa1100_reg);
if (ret == 0) {
- ret = driver_register(&sa11x0_serial_driver);
+ ret = platform_driver_register(&sa11x0_serial_driver);
if (ret)
uart_unregister_driver(&sa1100_reg);
}
@@ -919,7 +917,7 @@ static int __init sa1100_serial_init(void)
static void __exit sa1100_serial_exit(void)
{
- driver_unregister(&sa11x0_serial_driver);
+ platform_driver_unregister(&sa11x0_serial_driver);
uart_unregister_driver(&sa1100_reg);
}
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 427a238..2331296 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -209,33 +209,45 @@ static void uart_shutdown(struct uart_state *state)
struct uart_info *info = state->info;
struct uart_port *port = state->port;
- if (!(info->flags & UIF_INITIALIZED))
- return;
-
/*
- * Turn off DTR and RTS early.
+ * Set the TTY IO error marker
*/
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
- uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ if (info->tty)
+ set_bit(TTY_IO_ERROR, &info->tty->flags);
- /*
- * clear delta_msr_wait queue to avoid mem leaks: we may free
- * the irq here so the queue might never be woken up. Note
- * that we won't end up waiting on delta_msr_wait again since
- * any outstanding file descriptors should be pointing at
- * hung_up_tty_fops now.
- */
- wake_up_interruptible(&info->delta_msr_wait);
+ if (info->flags & UIF_INITIALIZED) {
+ info->flags &= ~UIF_INITIALIZED;
- /*
- * Free the IRQ and disable the port.
- */
- port->ops->shutdown(port);
+ /*
+ * Turn off DTR and RTS early.
+ */
+ if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+ uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+
+ /*
+ * clear delta_msr_wait queue to avoid mem leaks: we may free
+ * the irq here so the queue might never be woken up. Note
+ * that we won't end up waiting on delta_msr_wait again since
+ * any outstanding file descriptors should be pointing at
+ * hung_up_tty_fops now.
+ */
+ wake_up_interruptible(&info->delta_msr_wait);
+
+ /*
+ * Free the IRQ and disable the port.
+ */
+ port->ops->shutdown(port);
+
+ /*
+ * Ensure that the IRQ handler isn't running on another CPU.
+ */
+ synchronize_irq(port->irq);
+ }
/*
- * Ensure that the IRQ handler isn't running on another CPU.
+ * kill off our tasklet
*/
- synchronize_irq(port->irq);
+ tasklet_kill(&info->tlet);
/*
* Free the transmit buffer page.
@@ -244,15 +256,6 @@ static void uart_shutdown(struct uart_state *state)
free_page((unsigned long)info->xmit.buf);
info->xmit.buf = NULL;
}
-
- /*
- * kill off our tasklet
- */
- tasklet_kill(&info->tlet);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
-
- info->flags &= ~UIF_INITIALIZED;
}
/**
@@ -1928,14 +1931,25 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
if (state->info && state->info->flags & UIF_INITIALIZED) {
struct uart_ops *ops = port->ops;
+ int ret;
ops->set_mctrl(port, 0);
- ops->startup(port);
- uart_change_speed(state, NULL);
- spin_lock_irq(&port->lock);
- ops->set_mctrl(port, port->mctrl);
- ops->start_tx(port);
- spin_unlock_irq(&port->lock);
+ ret = ops->startup(port);
+ if (ret == 0) {
+ uart_change_speed(state, NULL);
+ spin_lock_irq(&port->lock);
+ ops->set_mctrl(port, port->mctrl);
+ ops->start_tx(port);
+ spin_unlock_irq(&port->lock);
+ } else {
+ /*
+ * Failed to resume - maybe hardware went away?
+ * Clear the "initialized" flag so we won't try
+ * to call the low level drivers shutdown method.
+ */
+ state->info->flags &= ~UIF_INITIALIZED;
+ uart_shutdown(state);
+ }
}
up(&state->sem);
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index 01696b3..865d4de 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -924,7 +924,7 @@ static struct uart_driver siu_uart_driver = {
.cons = SERIAL_VR41XX_CONSOLE,
};
-static int siu_probe(struct device *dev)
+static int siu_probe(struct platform_device *dev)
{
struct uart_port *port;
int num, i, retval;
@@ -941,7 +941,7 @@ static int siu_probe(struct device *dev)
for (i = 0; i < num; i++) {
port = &siu_uart_ports[i];
port->ops = &siu_uart_ops;
- port->dev = dev;
+ port->dev = &dev->dev;
retval = uart_add_one_port(&siu_uart_driver, port);
if (retval < 0) {
@@ -958,14 +958,14 @@ static int siu_probe(struct device *dev)
return 0;
}
-static int siu_remove(struct device *dev)
+static int siu_remove(struct platform_device *dev)
{
struct uart_port *port;
int i;
for (i = 0; i < siu_uart_driver.nr; i++) {
port = &siu_uart_ports[i];
- if (port->dev == dev) {
+ if (port->dev == &dev->dev) {
uart_remove_one_port(&siu_uart_driver, port);
port->dev = NULL;
}
@@ -976,7 +976,7 @@ static int siu_remove(struct device *dev)
return 0;
}
-static int siu_suspend(struct device *dev, pm_message_t state)
+static int siu_suspend(struct platform_device *dev, pm_message_t state)
{
struct uart_port *port;
int i;
@@ -984,7 +984,7 @@ static int siu_suspend(struct device *dev, pm_message_t state)
for (i = 0; i < siu_uart_driver.nr; i++) {
port = &siu_uart_ports[i];
if ((port->type == PORT_VR41XX_SIU ||
- port->type == PORT_VR41XX_DSIU) && port->dev == dev)
+ port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev)
uart_suspend_port(&siu_uart_driver, port);
}
@@ -992,7 +992,7 @@ static int siu_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int siu_resume(struct device *dev)
+static int siu_resume(struct platform_device *dev)
{
struct uart_port *port;
int i;
@@ -1000,7 +1000,7 @@ static int siu_resume(struct device *dev)
for (i = 0; i < siu_uart_driver.nr; i++) {
port = &siu_uart_ports[i];
if ((port->type == PORT_VR41XX_SIU ||
- port->type == PORT_VR41XX_DSIU) && port->dev == dev)
+ port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev)
uart_resume_port(&siu_uart_driver, port);
}
@@ -1009,13 +1009,14 @@ static int siu_resume(struct device *dev)
static struct platform_device *siu_platform_device;
-static struct device_driver siu_device_driver = {
- .name = "SIU",
- .bus = &platform_bus_type,
+static struct platform_driver siu_device_driver = {
.probe = siu_probe,
.remove = siu_remove,
.suspend = siu_suspend,
.resume = siu_resume,
+ .driver = {
+ .name = "SIU",
+ },
};
static int __devinit vr41xx_siu_init(void)
@@ -1026,7 +1027,7 @@ static int __devinit vr41xx_siu_init(void)
if (IS_ERR(siu_platform_device))
return PTR_ERR(siu_platform_device);
- retval = driver_register(&siu_device_driver);
+ retval = platform_driver_register(&siu_device_driver);
if (retval < 0)
platform_device_unregister(siu_platform_device);
@@ -1035,7 +1036,7 @@ static int __devinit vr41xx_siu_init(void)
static void __devexit vr41xx_siu_exit(void)
{
- driver_unregister(&siu_device_driver);
+ platform_driver_unregister(&siu_device_driver);
platform_device_unregister(siu_platform_device);
}
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index c52af73..6756d0f 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -6,7 +6,7 @@
*
* DECstation changes
* Copyright (C) 1998-2000 Harald Koerfgen
- * Copyright (C) 2000, 2001, 2002, 2003, 2004 Maciej W. Rozycki
+ * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Maciej W. Rozycki
*
* For the rest of the code the original Copyright applies:
* Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
@@ -55,6 +55,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/ioport.h>
+#include <linux/spinlock.h>
#ifdef CONFIG_SERIAL_DEC_CONSOLE
#include <linux/console.h>
#endif
@@ -63,7 +64,6 @@
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
#include <asm/bootinfo.h>
#include <asm/dec/interrupts.h>
@@ -128,6 +128,8 @@ static struct zs_parms ds_parms = {
#define BUS_PRESENT (DS_BUS_PRESENT)
+DEFINE_SPINLOCK(zs_lock);
+
struct dec_zschannel zs_channels[NUM_CHANNELS];
struct dec_serial zs_soft[NUM_CHANNELS];
int zs_channels_found;
@@ -159,8 +161,6 @@ static unsigned char zs_init_regs[16] __initdata = {
0 /* write 15 */
};
-DECLARE_TASK_QUEUE(tq_zs_serial);
-
static struct tty_driver *serial_driver;
/* serial subtype definitions */
@@ -294,8 +294,7 @@ static inline void zs_rtsdtr(struct dec_serial *info, int which, int set)
{
unsigned long flags;
-
- save_flags(flags); cli();
+ spin_lock_irqsave(&zs_lock, flags);
if (info->zs_channel != info->zs_chan_a) {
if (set) {
info->zs_chan_a->curregs[5] |= (which & (RTS | DTR));
@@ -304,7 +303,7 @@ static inline void zs_rtsdtr(struct dec_serial *info, int which, int set)
}
write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]);
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
}
/* Utility routines for the Zilog */
@@ -345,12 +344,10 @@ static inline void rs_recv_clear(struct dec_zschannel *zsc)
* This routine is used by the interrupt handler to schedule
* processing in the software interrupt portion of the driver.
*/
-static _INLINE_ void rs_sched_event(struct dec_serial *info,
- int event)
+static _INLINE_ void rs_sched_event(struct dec_serial *info, int event)
{
info->event |= 1 << event;
- queue_task(&info->tqueue, &tq_zs_serial);
- mark_bh(SERIAL_BH);
+ tasklet_schedule(&info->tlet);
}
static _INLINE_ void receive_chars(struct dec_serial *info,
@@ -497,9 +494,10 @@ static _INLINE_ void status_handle(struct dec_serial *info)
/*
* This is the serial driver's generic interrupt routine
*/
-void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct dec_serial *info = (struct dec_serial *) dev_id;
+ irqreturn_t status = IRQ_NONE;
unsigned char zs_intreg;
int shift;
@@ -521,6 +519,8 @@ void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
if ((zs_intreg & CHAN_IRQMASK) == 0)
break;
+ status = IRQ_HANDLED;
+
if (zs_intreg & CHBRxIP) {
receive_chars(info, regs);
}
@@ -534,6 +534,8 @@ void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
/* Why do we need this ? */
write_zsreg(info->zs_channel, 0, RES_H_IUS);
+
+ return status;
}
#ifdef ZS_DEBUG_REGS
@@ -578,12 +580,12 @@ static void rs_stop(struct tty_struct *tty)
return;
#if 1
- save_flags(flags); cli();
+ spin_lock_irqsave(&zs_lock, flags);
if (info->zs_channel->curregs[5] & TxENAB) {
info->zs_channel->curregs[5] &= ~TxENAB;
write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]);
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
#endif
}
@@ -595,7 +597,7 @@ static void rs_start(struct tty_struct *tty)
if (serial_paranoia_check(info, tty->name, "rs_start"))
return;
- save_flags(flags); cli();
+ spin_lock_irqsave(&zs_lock, flags);
#if 1
if (info->xmit_cnt && info->xmit_buf && !(info->zs_channel->curregs[5] & TxENAB)) {
info->zs_channel->curregs[5] |= TxENAB;
@@ -606,7 +608,7 @@ static void rs_start(struct tty_struct *tty)
transmit_chars(info);
}
#endif
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
}
/*
@@ -618,12 +620,8 @@ static void rs_start(struct tty_struct *tty)
* interrupt driver proper are done; the interrupt driver schedules
* them using rs_sched_event(), and they get done here.
*/
-static void do_serial_bh(void)
-{
- run_task_queue(&tq_zs_serial);
-}
-static void do_softint(void *private_)
+static void do_softint(unsigned long private_)
{
struct dec_serial *info = (struct dec_serial *) private_;
struct tty_struct *tty;
@@ -634,10 +632,11 @@ static void do_softint(void *private_)
if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
tty_wakeup(tty);
+ wake_up_interruptible(&tty->write_wait);
}
}
-int zs_startup(struct dec_serial * info)
+static int zs_startup(struct dec_serial * info)
{
unsigned long flags;
@@ -650,7 +649,7 @@ int zs_startup(struct dec_serial * info)
return -ENOMEM;
}
- save_flags(flags); cli();
+ spin_lock_irqsave(&zs_lock, flags);
#ifdef SERIAL_DEBUG_OPEN
printk("starting up ttyS%d (irq %d)...", info->line, info->irq);
@@ -706,7 +705,7 @@ int zs_startup(struct dec_serial * info)
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
info->flags |= ZILOG_INITIALIZED;
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
return 0;
}
@@ -726,7 +725,7 @@ static void shutdown(struct dec_serial * info)
info->irq);
#endif
- save_flags(flags); cli(); /* Disable interrupts */
+ spin_lock_irqsave(&zs_lock, flags);
if (info->xmit_buf) {
free_page((unsigned long) info->xmit_buf);
@@ -749,7 +748,7 @@ static void shutdown(struct dec_serial * info)
set_bit(TTY_IO_ERROR, &info->tty->flags);
info->flags &= ~ZILOG_INITIALIZED;
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
}
/*
@@ -785,7 +784,7 @@ static void change_speed(struct dec_serial *info)
i += 15;
}
- save_flags(flags); cli();
+ spin_lock_irqsave(&zs_lock, flags);
info->zs_baud = baud_table[i];
if (info->zs_baud) {
brg = BPS_TO_BRG(info->zs_baud, zs_parms->clock/info->clk_divisor);
@@ -858,7 +857,7 @@ static void change_speed(struct dec_serial *info)
/* Load up the new values */
load_zsregs(info->zs_channel, info->zs_channel->curregs);
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
}
static void rs_flush_chars(struct tty_struct *tty)
@@ -874,9 +873,9 @@ static void rs_flush_chars(struct tty_struct *tty)
return;
/* Enable transmitter */
- save_flags(flags); cli();
+ spin_lock_irqsave(&zs_lock, flags);
transmit_chars(info);
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
}
static int rs_write(struct tty_struct * tty,
@@ -892,26 +891,17 @@ static int rs_write(struct tty_struct * tty,
if (!tty || !info->xmit_buf)
return 0;
- save_flags(flags);
while (1) {
- cli();
+ spin_lock_irqsave(&zs_lock, flags);
c = min(count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
SERIAL_XMIT_SIZE - info->xmit_head));
if (c <= 0)
break;
- if (from_user) {
- down(&tmp_buf_sem);
- copy_from_user(tmp_buf, buf, c);
- c = min(c, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
- SERIAL_XMIT_SIZE - info->xmit_head));
- memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
- up(&tmp_buf_sem);
- } else
- memcpy(info->xmit_buf + info->xmit_head, buf, c);
+ memcpy(info->xmit_buf + info->xmit_head, buf, c);
info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
info->xmit_cnt += c;
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
buf += c;
count -= c;
total += c;
@@ -920,7 +910,7 @@ static int rs_write(struct tty_struct * tty,
if (info->xmit_cnt && !tty->stopped && !info->tx_stopped
&& !info->tx_active)
transmit_chars(info);
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
return total;
}
@@ -952,9 +942,9 @@ static void rs_flush_buffer(struct tty_struct *tty)
if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
return;
- cli();
+ spin_lock_irq(&zs_lock);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
- sti();
+ spin_unlock_irq(&zs_lock);
tty_wakeup(tty);
}
@@ -982,11 +972,11 @@ static void rs_throttle(struct tty_struct * tty)
return;
if (I_IXOFF(tty)) {
- save_flags(flags); cli();
+ spin_lock_irqsave(&zs_lock, flags);
info->x_char = STOP_CHAR(tty);
if (!info->tx_active)
transmit_chars(info);
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
}
if (C_CRTSCTS(tty)) {
@@ -1010,7 +1000,7 @@ static void rs_unthrottle(struct tty_struct * tty)
return;
if (I_IXOFF(tty)) {
- save_flags(flags); cli();
+ spin_lock_irqsave(&zs_lock, flags);
if (info->x_char)
info->x_char = 0;
else {
@@ -1018,7 +1008,7 @@ static void rs_unthrottle(struct tty_struct * tty)
if (!info->tx_active)
transmit_chars(info);
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
}
if (C_CRTSCTS(tty)) {
@@ -1111,9 +1101,9 @@ static int get_lsr_info(struct dec_serial * info, unsigned int *value)
{
unsigned char status;
- cli();
+ spin_lock(&zs_lock);
status = read_zsreg(info->zs_channel, 0);
- sti();
+ spin_unlock_irq(&zs_lock);
put_user(status,value);
return 0;
}
@@ -1136,11 +1126,11 @@ static int rs_tiocmget(struct tty_struct *tty, struct file *file)
if (info->zs_channel == info->zs_chan_a)
result = 0;
else {
- cli();
+ spin_lock(&zs_lock);
control = info->zs_chan_a->curregs[5];
status_a = read_zsreg(info->zs_chan_a, 0);
status_b = read_zsreg(info->zs_channel, 0);
- sti();
+ spin_unlock_irq(&zs_lock);
result = ((control & RTS) ? TIOCM_RTS: 0)
| ((control & DTR) ? TIOCM_DTR: 0)
| ((status_b & DCD) ? TIOCM_CAR: 0)
@@ -1155,8 +1145,6 @@ static int rs_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
struct dec_serial * info = (struct dec_serial *)tty->driver_data;
- int error;
- unsigned int arg, bits;
if (info->hook)
return -ENODEV;
@@ -1170,8 +1158,7 @@ static int rs_tiocmset(struct tty_struct *tty, struct file *file,
if (info->zs_channel == info->zs_chan_a)
return 0;
- get_user(arg, value);
- cli();
+ spin_lock(&zs_lock);
if (set & TIOCM_RTS)
info->zs_chan_a->curregs[5] |= RTS;
if (set & TIOCM_DTR)
@@ -1181,7 +1168,7 @@ static int rs_tiocmset(struct tty_struct *tty, struct file *file,
if (clear & TIOCM_DTR)
info->zs_chan_a->curregs[5] &= ~DTR;
write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]);
- sti();
+ spin_unlock_irq(&zs_lock);
return 0;
}
@@ -1198,19 +1185,18 @@ static void rs_break(struct tty_struct *tty, int break_state)
if (!info->port)
return;
- save_flags(flags); cli();
+ spin_lock_irqsave(&zs_lock, flags);
if (break_state == -1)
info->zs_channel->curregs[5] |= SND_BRK;
else
info->zs_channel->curregs[5] &= ~SND_BRK;
write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]);
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
}
static int rs_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg)
{
- int error;
struct dec_serial * info = (struct dec_serial *)tty->driver_data;
if (info->hook)
@@ -1287,10 +1273,10 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
return;
- save_flags(flags); cli();
+ spin_lock_irqsave(&zs_lock, flags);
if (tty_hung_up_p(filp)) {
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
return;
}
@@ -1315,7 +1301,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
info->count = 0;
}
if (info->count) {
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
return;
}
info->flags |= ZILOG_CLOSING;
@@ -1358,7 +1344,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
}
info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CLOSING);
wake_up_interruptible(&info->close_wait);
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
}
/*
@@ -1398,7 +1384,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
/*
* rs_hangup() --- called by tty_hangup() when a hangup is signaled.
*/
-void rs_hangup(struct tty_struct *tty)
+static void rs_hangup(struct tty_struct *tty)
{
struct dec_serial * info = (struct dec_serial *)tty->driver_data;
@@ -1466,16 +1452,16 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
printk("block_til_ready before block: ttyS%d, count = %d\n",
info->line, info->count);
#endif
- cli();
+ spin_lock(&zs_lock);
if (!tty_hung_up_p(filp))
info->count--;
- sti();
+ spin_unlock_irq(&zs_lock);
info->blocked_open++;
while (1) {
- cli();
+ spin_lock(&zs_lock);
if (tty->termios->c_cflag & CBAUD)
zs_rtsdtr(info, RTS | DTR, 1);
- sti();
+ spin_unlock_irq(&zs_lock);
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
!(info->flags & ZILOG_INITIALIZED)) {
@@ -1523,7 +1509,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
* the IRQ chain. It also performs the serial-specific
* initialization for the tty structure.
*/
-int rs_open(struct tty_struct *tty, struct file * filp)
+static int rs_open(struct tty_struct *tty, struct file * filp)
{
struct dec_serial *info;
int retval, line;
@@ -1706,7 +1692,7 @@ static void __init probe_sccs(void)
}
}
- save_and_cli(flags);
+ spin_lock_irqsave(&zs_lock, flags);
for (n = 0; n < zs_channels_found; n++) {
if (n % 2 == 0) {
write_zsreg(zs_soft[n].zs_chan_a, R9, FHWRES);
@@ -1716,7 +1702,7 @@ static void __init probe_sccs(void)
load_zsregs(zs_soft[n].zs_channel,
zs_soft[n].zs_channel->curregs);
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
}
static struct tty_operations serial_ops = {
@@ -1749,9 +1735,6 @@ int __init zs_init(void)
if(!BUS_PRESENT)
return -ENODEV;
- /* Setup base handler, and timer table. */
- init_bh(SERIAL_BH, do_serial_bh);
-
/* Find out how many Z8530 SCCs we have */
if (zs_chain == 0)
probe_sccs();
@@ -1800,8 +1783,7 @@ int __init zs_init(void)
info->event = 0;
info->count = 0;
info->blocked_open = 0;
- info->tqueue.routine = do_softint;
- info->tqueue.data = info;
+ tasklet_init(&info->tlet, do_softint, (unsigned long)info);
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
printk("ttyS%02d at 0x%08x (irq = %d) is a Z85C30 SCC\n",
@@ -1833,8 +1815,7 @@ int __init zs_init(void)
/*
* polling I/O routines
*/
-static int
-zs_poll_tx_char(void *handle, unsigned char ch)
+static int zs_poll_tx_char(void *handle, unsigned char ch)
{
struct dec_serial *info = handle;
struct dec_zschannel *chan = info->zs_channel;
@@ -1857,8 +1838,7 @@ zs_poll_tx_char(void *handle, unsigned char ch)
return -ENODEV;
}
-static int
-zs_poll_rx_char(void *handle)
+static int zs_poll_rx_char(void *handle)
{
struct dec_serial *info = handle;
struct dec_zschannel *chan = info->zs_channel;
@@ -2037,7 +2017,7 @@ static int __init serial_console_setup(struct console *co, char *options)
}
co->cflag = cflag;
- save_and_cli(flags);
+ spin_lock_irqsave(&zs_lock, flags);
/*
* Set up the baud rate generator.
@@ -2092,7 +2072,7 @@ static int __init serial_console_setup(struct console *co, char *options)
zs_soft[co->index].clk_divisor = clk_divisor;
zs_soft[co->index].zs_baud = get_zsbaud(&zs_soft[co->index]);
- restore_flags(flags);
+ spin_unlock_irqrestore(&zs_lock, flags);
return 0;
}
@@ -2229,5 +2209,3 @@ void __init zs_kgdb_hook(int tty_num)
set_debug_traps(); /* init stub */
}
#endif /* ifdef CONFIG_KGDB */
-
-
diff --git a/drivers/tc/zs.h b/drivers/tc/zs.h
index c52edff..1351220 100644
--- a/drivers/tc/zs.h
+++ b/drivers/tc/zs.h
@@ -6,14 +6,14 @@
*
* Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 2004 Maciej W. Rozycki
+ * Copyright (C) 2004, 2005 Maciej W. Rozycki
*/
#ifndef _DECSERIAL_H
#define _DECSERIAL_H
#include <asm/dec/serial.h>
-#define NUM_ZSREGS 16
+#define NUM_ZSREGS 16
struct serial_struct {
int type;
@@ -139,8 +139,7 @@ struct dec_serial {
int xmit_head;
int xmit_tail;
int xmit_cnt;
- struct tq_struct tqueue;
- struct tq_struct tqueue_hangup;
+ struct tasklet_struct tlet;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
};
@@ -282,7 +281,7 @@ struct dec_serial {
#define DLC 4 /* Disable Lower Chain */
#define MIE 8 /* Master Interrupt Enable */
#define STATHI 0x10 /* Status high */
-#define SOFTACK 0x20 /* Software Interrupt Acknowledge */
+#define SOFTACK 0x20 /* Software Interrupt Acknowledge */
#define NORESET 0 /* No reset on write to R9 */
#define CHRB 0x40 /* Reset channel B */
#define CHRA 0x80 /* Reset channel A */
@@ -395,8 +394,8 @@ struct dec_serial {
/* Read Register 15 (value of WR 15) */
/* Misc macros */
-#define ZS_CLEARERR(channel) (write_zsreg(channel, 0, ERR_RES))
-#define ZS_CLEARFIFO(channel) do { volatile unsigned char garbage; \
+#define ZS_CLEARERR(channel) (write_zsreg(channel, 0, ERR_RES))
+#define ZS_CLEARFIFO(channel) do { volatile unsigned char garbage; \
garbage = read_zsdata(channel); \
garbage = read_zsdata(channel); \
garbage = read_zsdata(channel); \
diff --git a/drivers/usb/atm/Makefile b/drivers/usb/atm/Makefile
index 751f297..8509971 100644
--- a/drivers/usb/atm/Makefile
+++ b/drivers/usb/atm/Makefile
@@ -6,3 +6,7 @@ obj-$(CONFIG_USB_CXACRU) += cxacru.o
obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o
obj-$(CONFIG_USB_ATM) += usbatm.o
obj-$(CONFIG_USB_XUSBATM) += xusbatm.o
+
+ifeq ($(CONFIG_USB_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h
index 9366464..1adacd6 100644
--- a/drivers/usb/atm/usbatm.h
+++ b/drivers/usb/atm/usbatm.h
@@ -27,14 +27,9 @@
#include <linux/config.h>
/*
-#define DEBUG
#define VERBOSE_DEBUG
*/
-#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
-# define DEBUG
-#endif
-
#include <asm/semaphore.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index dd1c4d2..86d5c38 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -14,3 +14,7 @@ ifeq ($(CONFIG_USB_DEVICEFS),y)
endif
obj-$(CONFIG_USB) += usbcore.o
+
+ifeq ($(CONFIG_USB_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 57e800a..419c994 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -15,14 +15,6 @@
#include <asm/scatterlist.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
-
-
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
-
#include <linux/usb.h>
#include "hcd.h"
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 9930195..a9d89c7 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -1,9 +1,4 @@
#include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-#define DEBUG
-#endif
-
#include <linux/usb.h>
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 942cd43..b1d6e9a 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1392,13 +1392,13 @@ static int proc_ioctl_default(struct dev_state *ps, void __user *arg)
}
#ifdef CONFIG_COMPAT
-static int proc_ioctl_compat(struct dev_state *ps, void __user *arg)
+static int proc_ioctl_compat(struct dev_state *ps, compat_uptr_t arg)
{
struct usbdevfs_ioctl32 __user *uioc;
struct usbdevfs_ioctl ctrl;
u32 udata;
- uioc = compat_ptr(arg);
+ uioc = compat_ptr((long)arg);
if (get_user(ctrl.ifno, &uioc->ifno) ||
get_user(ctrl.ioctl_code, &uioc->ioctl_code) ||
__get_user(udata, &uioc->data))
@@ -1511,7 +1511,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
case USBDEVFS_IOCTL32:
snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__);
- ret = proc_ioctl_compat(ps, p);
+ ret = proc_ioctl_compat(ps, (compat_uptr_t)(long)p);
break;
#endif
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index e695308..37b1336 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -19,12 +19,6 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
-
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
#include <linux/usb.h>
#include "usb.h"
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 84d9e69..7feb829 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -17,13 +17,6 @@
*/
#include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 6c7ca5b..5e5f65a 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -23,11 +23,6 @@
*/
#include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-#define DEBUG
-#endif
-
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 256d9f6..8407279 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -9,11 +9,6 @@
*/
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 12f490f..c44bbed 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -46,7 +46,6 @@
static struct super_operations usbfs_ops;
static struct file_operations default_file_operations;
-static struct inode_operations usbfs_dir_inode_operations;
static struct vfsmount *usbfs_mount;
static int usbfs_mount_count; /* = 0 */
static int ignore_mount = 0;
@@ -262,7 +261,7 @@ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t de
inode->i_fop = &default_file_operations;
break;
case S_IFDIR:
- inode->i_op = &usbfs_dir_inode_operations;
+ inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
@@ -417,10 +416,6 @@ static struct file_operations default_file_operations = {
.llseek = default_file_lseek,
};
-static struct inode_operations usbfs_dir_inode_operations = {
- .lookup = simple_lookup,
-};
-
static struct super_operations usbfs_ops = {
.statfs = simple_statfs,
.drop_inode = generic_delete_inode,
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 644a3d4..fe74f99 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -3,13 +3,6 @@
*/
#include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
-
#include <linux/pci.h> /* for scatterlist macros */
#include <linux/usb.h>
#include <linux/module.h>
@@ -1457,12 +1450,11 @@ free_interfaces:
*/
for (i = 0; i < nintf; ++i) {
struct usb_interface *intf = cp->interface[i];
- struct usb_host_interface *alt = intf->cur_altsetting;
dev_dbg (&dev->dev,
"adding %s (config #%d, interface %d)\n",
intf->dev.bus_id, configuration,
- alt->desc.bInterfaceNumber);
+ intf->cur_altsetting->desc.bInterfaceNumber);
ret = device_add (&intf->dev);
if (ret != 0) {
dev_err(&dev->dev,
diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c
index 37da059..fbbebab 100644
--- a/drivers/usb/core/notify.c
+++ b/drivers/usb/core/notify.c
@@ -12,13 +12,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/notifier.h>
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
#include <linux/usb.h>
-
#include "usb.h"
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index edd83e0..71d8813 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -12,14 +12,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
-
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
#include <linux/usb.h>
-
#include "usb.h"
/* endpoint stuff */
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index f2a1fed..0817967 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -4,12 +4,6 @@
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/init.h>
-
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
#include <linux/usb.h>
#include "hcd.h"
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 0eefff7..e197ce9 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -22,13 +22,6 @@
*/
#include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
-
#include <linux/module.h>
#include <linux/string.h>
#include <linux/bitops.h>
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 9045190..c655d46 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -896,7 +896,7 @@ dummy_gadget_release (struct device *dev)
#endif
}
-static int dummy_udc_probe (struct device *dev)
+static int dummy_udc_probe (struct platform_device *dev)
{
struct dummy *dum = the_controller;
int rc;
@@ -909,7 +909,7 @@ static int dummy_udc_probe (struct device *dev)
dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0);
strcpy (dum->gadget.dev.bus_id, "gadget");
- dum->gadget.dev.parent = dev;
+ dum->gadget.dev.parent = &dev->dev;
dum->gadget.dev.release = dummy_gadget_release;
rc = device_register (&dum->gadget.dev);
if (rc < 0)
@@ -919,59 +919,60 @@ static int dummy_udc_probe (struct device *dev)
usb_bus_get (&dummy_to_hcd (dum)->self);
#endif
- dev_set_drvdata (dev, dum);
+ platform_set_drvdata (dev, dum);
device_create_file (&dum->gadget.dev, &dev_attr_function);
return rc;
}
-static int dummy_udc_remove (struct device *dev)
+static int dummy_udc_remove (struct platform_device *dev)
{
- struct dummy *dum = dev_get_drvdata (dev);
+ struct dummy *dum = platform_get_drvdata (dev);
- dev_set_drvdata (dev, NULL);
+ platform_set_drvdata (dev, NULL);
device_remove_file (&dum->gadget.dev, &dev_attr_function);
device_unregister (&dum->gadget.dev);
return 0;
}
-static int dummy_udc_suspend (struct device *dev, pm_message_t state)
+static int dummy_udc_suspend (struct platform_device *dev, pm_message_t state)
{
- struct dummy *dum = dev_get_drvdata(dev);
+ struct dummy *dum = platform_get_drvdata(dev);
- dev_dbg (dev, "%s\n", __FUNCTION__);
+ dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
spin_lock_irq (&dum->lock);
dum->udc_suspended = 1;
set_link_state (dum);
spin_unlock_irq (&dum->lock);
- dev->power.power_state = state;
+ dev->dev.power.power_state = state;
usb_hcd_poll_rh_status (dummy_to_hcd (dum));
return 0;
}
-static int dummy_udc_resume (struct device *dev)
+static int dummy_udc_resume (struct platform_device *dev)
{
- struct dummy *dum = dev_get_drvdata(dev);
+ struct dummy *dum = platform_get_drvdata(dev);
- dev_dbg (dev, "%s\n", __FUNCTION__);
+ dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
spin_lock_irq (&dum->lock);
dum->udc_suspended = 0;
set_link_state (dum);
spin_unlock_irq (&dum->lock);
- dev->power.power_state = PMSG_ON;
+ dev->dev.power.power_state = PMSG_ON;
usb_hcd_poll_rh_status (dummy_to_hcd (dum));
return 0;
}
-static struct device_driver dummy_udc_driver = {
- .name = (char *) gadget_name,
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver dummy_udc_driver = {
.probe = dummy_udc_probe,
.remove = dummy_udc_remove,
.suspend = dummy_udc_suspend,
.resume = dummy_udc_resume,
+ .driver = {
+ .name = (char *) gadget_name,
+ .owner = THIS_MODULE,
+ },
};
/*-------------------------------------------------------------------------*/
@@ -1898,14 +1899,14 @@ static const struct hc_driver dummy_hcd = {
.bus_resume = dummy_bus_resume,
};
-static int dummy_hcd_probe (struct device *dev)
+static int dummy_hcd_probe (struct platform_device *dev)
{
struct usb_hcd *hcd;
int retval;
- dev_info (dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
+ dev_info(&dev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
- hcd = usb_create_hcd (&dummy_hcd, dev, dev->bus_id);
+ hcd = usb_create_hcd (&dummy_hcd, &dev->dev, dev->dev.bus_id);
if (!hcd)
return -ENOMEM;
the_controller = hcd_to_dummy (hcd);
@@ -1918,48 +1919,49 @@ static int dummy_hcd_probe (struct device *dev)
return retval;
}
-static int dummy_hcd_remove (struct device *dev)
+static int dummy_hcd_remove (struct platform_device *dev)
{
struct usb_hcd *hcd;
- hcd = dev_get_drvdata (dev);
+ hcd = platform_get_drvdata (dev);
usb_remove_hcd (hcd);
usb_put_hcd (hcd);
the_controller = NULL;
return 0;
}
-static int dummy_hcd_suspend (struct device *dev, pm_message_t state)
+static int dummy_hcd_suspend (struct platform_device *dev, pm_message_t state)
{
struct usb_hcd *hcd;
- dev_dbg (dev, "%s\n", __FUNCTION__);
- hcd = dev_get_drvdata (dev);
+ dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
+ hcd = platform_get_drvdata (dev);
hcd->state = HC_STATE_SUSPENDED;
return 0;
}
-static int dummy_hcd_resume (struct device *dev)
+static int dummy_hcd_resume (struct platform_device *dev)
{
struct usb_hcd *hcd;
- dev_dbg (dev, "%s\n", __FUNCTION__);
- hcd = dev_get_drvdata (dev);
+ dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
+ hcd = platform_get_drvdata (dev);
hcd->state = HC_STATE_RUNNING;
usb_hcd_poll_rh_status (hcd);
return 0;
}
-static struct device_driver dummy_hcd_driver = {
- .name = (char *) driver_name,
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver dummy_hcd_driver = {
.probe = dummy_hcd_probe,
.remove = dummy_hcd_remove,
.suspend = dummy_hcd_suspend,
.resume = dummy_hcd_resume,
+ .driver = {
+ .name = (char *) driver_name,
+ .owner = THIS_MODULE,
+ },
};
/*-------------------------------------------------------------------------*/
@@ -1995,11 +1997,11 @@ static int __init init (void)
if (usb_disabled ())
return -ENODEV;
- retval = driver_register (&dummy_hcd_driver);
+ retval = platform_driver_register (&dummy_hcd_driver);
if (retval < 0)
return retval;
- retval = driver_register (&dummy_udc_driver);
+ retval = platform_driver_register (&dummy_udc_driver);
if (retval < 0)
goto err_register_udc_driver;
@@ -2015,9 +2017,9 @@ static int __init init (void)
err_register_udc:
platform_device_unregister (&the_hcd_pdev);
err_register_hcd:
- driver_unregister (&dummy_udc_driver);
+ platform_driver_unregister (&dummy_udc_driver);
err_register_udc_driver:
- driver_unregister (&dummy_hcd_driver);
+ platform_driver_unregister (&dummy_hcd_driver);
return retval;
}
module_init (init);
@@ -2026,7 +2028,7 @@ static void __exit cleanup (void)
{
platform_device_unregister (&the_udc_pdev);
platform_device_unregister (&the_hcd_pdev);
- driver_unregister (&dummy_udc_driver);
- driver_unregister (&dummy_hcd_driver);
+ platform_driver_unregister (&dummy_udc_driver);
+ platform_driver_unregister (&dummy_hcd_driver);
}
module_exit (cleanup);
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 6544697..b0f3cd6 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1970,7 +1970,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
static struct pci_driver goku_pci_driver = {
.name = (char *) driver_name,
.id_table = pci_ids,
- .owner = THIS_MODULE,
.probe = goku_probe,
.remove = goku_remove,
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index bc6269f..e02fea5 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -2085,21 +2085,21 @@ static struct lh7a40x_udc memory = {
/*
* probe - binds to the platform device
*/
-static int lh7a40x_udc_probe(struct device *_dev)
+static int lh7a40x_udc_probe(struct platform_device *pdev)
{
struct lh7a40x_udc *dev = &memory;
int retval;
- DEBUG("%s: %p\n", __FUNCTION__, _dev);
+ DEBUG("%s: %p\n", __FUNCTION__, pdev);
spin_lock_init(&dev->lock);
- dev->dev = _dev;
+ dev->dev = &pdev->dev;
device_initialize(&dev->gadget.dev);
- dev->gadget.dev.parent = _dev;
+ dev->gadget.dev.parent = &pdev->dev;
the_controller = dev;
- dev_set_drvdata(_dev, dev);
+ platform_set_drvdata(pdev, dev);
udc_disable(dev);
udc_reinit(dev);
@@ -2119,11 +2119,11 @@ static int lh7a40x_udc_probe(struct device *_dev)
return retval;
}
-static int lh7a40x_udc_remove(struct device *_dev)
+static int lh7a40x_udc_remove(struct platform_device *pdev)
{
- struct lh7a40x_udc *dev = _dev->driver_data;
+ struct lh7a40x_udc *dev = platform_get_drvdata(pdev);
- DEBUG("%s: %p\n", __FUNCTION__, dev);
+ DEBUG("%s: %p\n", __FUNCTION__, pdev);
udc_disable(dev);
remove_proc_files();
@@ -2131,7 +2131,7 @@ static int lh7a40x_udc_remove(struct device *_dev)
free_irq(IRQ_USBINTR, dev);
- dev_set_drvdata(_dev, 0);
+ platform_set_drvdata(pdev, 0);
the_controller = 0;
@@ -2140,26 +2140,27 @@ static int lh7a40x_udc_remove(struct device *_dev)
/*-------------------------------------------------------------------------*/
-static struct device_driver udc_driver = {
- .name = (char *)driver_name,
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver udc_driver = {
.probe = lh7a40x_udc_probe,
.remove = lh7a40x_udc_remove
/* FIXME power management support */
/* .suspend = ... disable UDC */
/* .resume = ... re-enable UDC */
+ .driver = {
+ .name = (char *)driver_name,
+ .owner = THIS_MODULE,
+ },
};
static int __init udc_init(void)
{
DEBUG("%s: %s version %s\n", __FUNCTION__, driver_name, DRIVER_VERSION);
- return driver_register(&udc_driver);
+ return platform_driver_register(&udc_driver);
}
static void __exit udc_exit(void)
{
- driver_unregister(&udc_driver);
+ platform_driver_unregister(&udc_driver);
}
module_init(udc_init);
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 0dc6bb0..c32e1f7 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -2948,7 +2948,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
static struct pci_driver net2280_pci_driver = {
.name = (char *) driver_name,
.id_table = pci_ids,
- .owner = THIS_MODULE,
.probe = net2280_probe,
.remove = net2280_remove,
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 387692a..a8972d7 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -2707,18 +2707,17 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)
return 0;
}
-static int __init omap_udc_probe(struct device *dev)
+static int __init omap_udc_probe(struct platform_device *pdev)
{
- struct platform_device *odev = to_platform_device(dev);
int status = -ENODEV;
int hmc;
struct otg_transceiver *xceiv = NULL;
const char *type = NULL;
- struct omap_usb_config *config = dev->platform_data;
+ struct omap_usb_config *config = pdev->dev.platform_data;
/* NOTE: "knows" the order of the resources! */
- if (!request_mem_region(odev->resource[0].start,
- odev->resource[0].end - odev->resource[0].start + 1,
+ if (!request_mem_region(pdev->resource[0].start,
+ pdev->resource[0].end - pdev->resource[0].start + 1,
driver_name)) {
DBG("request_mem_region failed\n");
return -EBUSY;
@@ -2803,7 +2802,7 @@ bad_on_1710:
INFO("hmc mode %d, %s transceiver\n", hmc, type);
/* a "gadget" abstracts/virtualizes the controller */
- status = omap_udc_setup(odev, xceiv);
+ status = omap_udc_setup(pdev, xceiv);
if (status) {
goto cleanup0;
}
@@ -2821,28 +2820,28 @@ bad_on_1710:
udc->clr_halt = UDC_RESET_EP;
/* USB general purpose IRQ: ep0, state changes, dma, etc */
- status = request_irq(odev->resource[1].start, omap_udc_irq,
+ status = request_irq(pdev->resource[1].start, omap_udc_irq,
SA_SAMPLE_RANDOM, driver_name, udc);
if (status != 0) {
ERR( "can't get irq %ld, err %d\n",
- odev->resource[1].start, status);
+ pdev->resource[1].start, status);
goto cleanup1;
}
/* USB "non-iso" IRQ (PIO for all but ep0) */
- status = request_irq(odev->resource[2].start, omap_udc_pio_irq,
+ status = request_irq(pdev->resource[2].start, omap_udc_pio_irq,
SA_SAMPLE_RANDOM, "omap_udc pio", udc);
if (status != 0) {
ERR( "can't get irq %ld, err %d\n",
- odev->resource[2].start, status);
+ pdev->resource[2].start, status);
goto cleanup2;
}
#ifdef USE_ISO
- status = request_irq(odev->resource[3].start, omap_udc_iso_irq,
+ status = request_irq(pdev->resource[3].start, omap_udc_iso_irq,
SA_INTERRUPT, "omap_udc iso", udc);
if (status != 0) {
ERR("can't get irq %ld, err %d\n",
- odev->resource[3].start, status);
+ pdev->resource[3].start, status);
goto cleanup3;
}
#endif
@@ -2853,11 +2852,11 @@ bad_on_1710:
#ifdef USE_ISO
cleanup3:
- free_irq(odev->resource[2].start, udc);
+ free_irq(pdev->resource[2].start, udc);
#endif
cleanup2:
- free_irq(odev->resource[1].start, udc);
+ free_irq(pdev->resource[1].start, udc);
cleanup1:
kfree (udc);
@@ -2866,14 +2865,13 @@ cleanup1:
cleanup0:
if (xceiv)
put_device(xceiv->dev);
- release_mem_region(odev->resource[0].start,
- odev->resource[0].end - odev->resource[0].start + 1);
+ release_mem_region(pdev->resource[0].start,
+ pdev->resource[0].end - pdev->resource[0].start + 1);
return status;
}
-static int __exit omap_udc_remove(struct device *dev)
+static int __exit omap_udc_remove(struct platform_device *pdev)
{
- struct platform_device *odev = to_platform_device(dev);
DECLARE_COMPLETION(done);
if (!udc)
@@ -2891,13 +2889,13 @@ static int __exit omap_udc_remove(struct device *dev)
remove_proc_file();
#ifdef USE_ISO
- free_irq(odev->resource[3].start, udc);
+ free_irq(pdev->resource[3].start, udc);
#endif
- free_irq(odev->resource[2].start, udc);
- free_irq(odev->resource[1].start, udc);
+ free_irq(pdev->resource[2].start, udc);
+ free_irq(pdev->resource[1].start, udc);
- release_mem_region(odev->resource[0].start,
- odev->resource[0].end - odev->resource[0].start + 1);
+ release_mem_region(pdev->resource[0].start,
+ pdev->resource[0].end - pdev->resource[0].start + 1);
device_unregister(&udc->gadget.dev);
wait_for_completion(&done);
@@ -2915,7 +2913,7 @@ static int __exit omap_udc_remove(struct device *dev)
* may involve talking to an external transceiver (e.g. isp1301).
*/
-static int omap_udc_suspend(struct device *dev, pm_message_t message)
+static int omap_udc_suspend(struct platform_device *dev, pm_message_t message)
{
u32 devstat;
@@ -2935,7 +2933,7 @@ static int omap_udc_suspend(struct device *dev, pm_message_t message)
return 0;
}
-static int omap_udc_resume(struct device *dev)
+static int omap_udc_resume(struct platform_device *dev)
{
DBG("resume + wakeup/SRP\n");
omap_pullup(&udc->gadget, 1);
@@ -2947,14 +2945,15 @@ static int omap_udc_resume(struct device *dev)
/*-------------------------------------------------------------------------*/
-static struct device_driver udc_driver = {
- .name = (char *) driver_name,
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver udc_driver = {
.probe = omap_udc_probe,
.remove = __exit_p(omap_udc_remove),
.suspend = omap_udc_suspend,
.resume = omap_udc_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = (char *) driver_name,
+ },
};
static int __init udc_init(void)
@@ -2965,13 +2964,13 @@ static int __init udc_init(void)
#endif
"%s\n", driver_desc,
use_dma ? " (dma)" : "");
- return driver_register(&udc_driver);
+ return platform_driver_register(&udc_driver);
}
module_init(udc_init);
static void __exit udc_exit(void)
{
- driver_unregister(&udc_driver);
+ platform_driver_unregister(&udc_driver);
}
module_exit(udc_exit);
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 510d28a..bb028c5 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -2432,7 +2432,7 @@ static struct pxa2xx_udc memory = {
/*
* probe - binds to the platform device
*/
-static int __init pxa2xx_udc_probe(struct device *_dev)
+static int __init pxa2xx_udc_probe(struct platform_device *pdev)
{
struct pxa2xx_udc *dev = &memory;
int retval, out_dma = 1;
@@ -2495,19 +2495,19 @@ static int __init pxa2xx_udc_probe(struct device *_dev)
#endif
/* other non-static parts of init */
- dev->dev = _dev;
- dev->mach = _dev->platform_data;
+ dev->dev = &pdev->dev;
+ dev->mach = pdev->dev.platform_data;
init_timer(&dev->timer);
dev->timer.function = udc_watchdog;
dev->timer.data = (unsigned long) dev;
device_initialize(&dev->gadget.dev);
- dev->gadget.dev.parent = _dev;
- dev->gadget.dev.dma_mask = _dev->dma_mask;
+ dev->gadget.dev.parent = &pdev->dev;
+ dev->gadget.dev.dma_mask = pdev->dev.dma_mask;
the_controller = dev;
- dev_set_drvdata(_dev, dev);
+ platform_set_drvdata(pdev, dev);
udc_disable(dev);
udc_reinit(dev);
@@ -2559,14 +2559,14 @@ lubbock_fail0:
return 0;
}
-static void pxa2xx_udc_shutdown(struct device *_dev)
+static void pxa2xx_udc_shutdown(struct platform_device *_dev)
{
pullup_off();
}
-static int __exit pxa2xx_udc_remove(struct device *_dev)
+static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
{
- struct pxa2xx_udc *dev = dev_get_drvdata(_dev);
+ struct pxa2xx_udc *dev = platform_get_drvdata(pdev);
udc_disable(dev);
remove_proc_files();
@@ -2580,7 +2580,7 @@ static int __exit pxa2xx_udc_remove(struct device *_dev)
free_irq(LUBBOCK_USB_DISC_IRQ, dev);
free_irq(LUBBOCK_USB_IRQ, dev);
}
- dev_set_drvdata(_dev, NULL);
+ platform_set_drvdata(pdev, NULL);
the_controller = NULL;
return 0;
}
@@ -2601,9 +2601,9 @@ static int __exit pxa2xx_udc_remove(struct device *_dev)
* VBUS IRQs should probably be ignored so that the PXA device just acts
* "dead" to USB hosts until system resume.
*/
-static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state)
+static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
{
- struct pxa2xx_udc *udc = dev_get_drvdata(dev);
+ struct pxa2xx_udc *udc = platform_get_drvdata(dev);
if (!udc->mach->udc_command)
WARN("USB host won't detect disconnect!\n");
@@ -2612,9 +2612,9 @@ static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int pxa2xx_udc_resume(struct device *dev)
+static int pxa2xx_udc_resume(struct platform_device *dev)
{
- struct pxa2xx_udc *udc = dev_get_drvdata(dev);
+ struct pxa2xx_udc *udc = platform_get_drvdata(dev);
pullup(udc, 1);
@@ -2628,27 +2628,28 @@ static int pxa2xx_udc_resume(struct device *dev)
/*-------------------------------------------------------------------------*/
-static struct device_driver udc_driver = {
- .name = "pxa2xx-udc",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver udc_driver = {
.probe = pxa2xx_udc_probe,
.shutdown = pxa2xx_udc_shutdown,
.remove = __exit_p(pxa2xx_udc_remove),
.suspend = pxa2xx_udc_suspend,
.resume = pxa2xx_udc_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "pxa2xx-udc",
+ },
};
static int __init udc_init(void)
{
printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);
- return driver_register(&udc_driver);
+ return platform_driver_register(&udc_driver);
}
module_init(udc_init);
static void __exit udc_exit(void)
{
- driver_unregister(&udc_driver);
+ platform_driver_unregister(&udc_driver);
}
module_exit(udc_exit);
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 1450088..dfd9bd0 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -383,7 +383,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
static struct pci_driver ehci_pci_driver = {
.name = (char *) hcd_name,
.id_table = pci_ids,
- .owner = THIS_MODULE,
.probe = usb_hcd_pci_probe,
.remove = usb_hcd_pci_remove,
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index f9c3f5b..82f6498 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1633,17 +1633,15 @@ static struct hc_driver isp116x_hc_driver = {
/*----------------------------------------------------------------*/
-static int __init_or_module isp116x_remove(struct device *dev)
+static int __init_or_module isp116x_remove(struct platform_device *pdev)
{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct isp116x *isp116x;
- struct platform_device *pdev;
struct resource *res;
if (!hcd)
return 0;
isp116x = hcd_to_isp116x(hcd);
- pdev = container_of(dev, struct platform_device, dev);
remove_debug_file(isp116x);
usb_remove_hcd(hcd);
@@ -1660,18 +1658,16 @@ static int __init_or_module isp116x_remove(struct device *dev)
#define resource_len(r) (((r)->end - (r)->start) + 1)
-static int __init isp116x_probe(struct device *dev)
+static int __init isp116x_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct isp116x *isp116x;
- struct platform_device *pdev;
struct resource *addr, *data;
void __iomem *addr_reg;
void __iomem *data_reg;
int irq;
int ret = 0;
- pdev = container_of(dev, struct platform_device, dev);
if (pdev->num_resources < 3) {
ret = -ENODEV;
goto err1;
@@ -1685,7 +1681,7 @@ static int __init isp116x_probe(struct device *dev)
goto err1;
}
- if (dev->dma_mask) {
+ if (pdev->dev.dma_mask) {
DBG("DMA not supported\n");
ret = -EINVAL;
goto err1;
@@ -1711,7 +1707,7 @@ static int __init isp116x_probe(struct device *dev)
}
/* allocate and initialize hcd */
- hcd = usb_create_hcd(&isp116x_hc_driver, dev, dev->bus_id);
+ hcd = usb_create_hcd(&isp116x_hc_driver, &pdev->dev, pdev->dev.bus_id);
if (!hcd) {
ret = -ENOMEM;
goto err5;
@@ -1723,7 +1719,7 @@ static int __init isp116x_probe(struct device *dev)
isp116x->addr_reg = addr_reg;
spin_lock_init(&isp116x->lock);
INIT_LIST_HEAD(&isp116x->async);
- isp116x->board = dev->platform_data;
+ isp116x->board = pdev->dev.platform_data;
if (!isp116x->board) {
ERR("Platform data structure not initialized\n");
@@ -1764,13 +1760,13 @@ static int __init isp116x_probe(struct device *dev)
/*
Suspend of platform device
*/
-static int isp116x_suspend(struct device *dev, pm_message_t state)
+static int isp116x_suspend(struct platform_device *dev, pm_message_t state)
{
int ret = 0;
VDBG("%s: state %x\n", __func__, state);
- dev->power.power_state = state;
+ dev->dev.power.power_state = state;
return ret;
}
@@ -1778,13 +1774,13 @@ static int isp116x_suspend(struct device *dev, pm_message_t state)
/*
Resume platform device
*/
-static int isp116x_resume(struct device *dev)
+static int isp116x_resume(struct platform_device *dev)
{
int ret = 0;
- VDBG("%s: state %x\n", __func__, dev->power.power_state);
+ VDBG("%s: state %x\n", __func__, dev->dev.power.power_state);
- dev->power.power_state = PMSG_ON;
+ dev->dev.power.power_state = PMSG_ON;
return ret;
}
@@ -1796,13 +1792,14 @@ static int isp116x_resume(struct device *dev)
#endif
-static struct device_driver isp116x_driver = {
- .name = (char *)hcd_name,
- .bus = &platform_bus_type,
+static struct platform_driver isp116x_driver = {
.probe = isp116x_probe,
.remove = isp116x_remove,
.suspend = isp116x_suspend,
.resume = isp116x_resume,
+ .driver = {
+ .name = (char *)hcd_name,
+ },
};
/*-----------------------------------------------------------------*/
@@ -1813,14 +1810,14 @@ static int __init isp116x_init(void)
return -ENODEV;
INFO("driver %s, %s\n", hcd_name, DRIVER_VERSION);
- return driver_register(&isp116x_driver);
+ return platform_driver_register(&isp116x_driver);
}
module_init(isp116x_init);
static void __exit isp116x_cleanup(void)
{
- driver_unregister(&isp116x_driver);
+ platform_driver_unregister(&isp116x_driver);
}
module_exit(isp116x_cleanup);
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index f0c78cf..d9cf3b3 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -225,9 +225,8 @@ static const struct hc_driver ohci_au1xxx_hc_driver = {
/*-------------------------------------------------------------------------*/
-static int ohci_hcd_au1xxx_drv_probe(struct device *dev)
+static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
int ret;
pr_debug ("In ohci_hcd_au1xxx_drv_probe");
@@ -239,39 +238,37 @@ static int ohci_hcd_au1xxx_drv_probe(struct device *dev)
return ret;
}
-static int ohci_hcd_au1xxx_drv_remove(struct device *dev)
+static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_hcd_au1xxx_remove(hcd, pdev);
return 0;
}
/*TBD*/
-/*static int ohci_hcd_au1xxx_drv_suspend(struct device *dev)
+/*static int ohci_hcd_au1xxx_drv_suspend(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
return 0;
}
-static int ohci_hcd_au1xxx_drv_resume(struct device *dev)
+static int ohci_hcd_au1xxx_drv_resume(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
return 0;
}
*/
-static struct device_driver ohci_hcd_au1xxx_driver = {
- .name = "au1xxx-ohci",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver ohci_hcd_au1xxx_driver = {
.probe = ohci_hcd_au1xxx_drv_probe,
.remove = ohci_hcd_au1xxx_drv_remove,
/*.suspend = ohci_hcd_au1xxx_drv_suspend, */
/*.resume = ohci_hcd_au1xxx_drv_resume, */
+ .driver = {
+ .name = "au1xxx-ohci",
+ .owner = THIS_MODULE,
+ },
};
static int __init ohci_hcd_au1xxx_init (void)
@@ -280,12 +277,12 @@ static int __init ohci_hcd_au1xxx_init (void)
pr_debug ("block sizes: ed %d td %d\n",
sizeof (struct ed), sizeof (struct td));
- return driver_register(&ohci_hcd_au1xxx_driver);
+ return platform_driver_register(&ohci_hcd_au1xxx_driver);
}
static void __exit ohci_hcd_au1xxx_cleanup (void)
{
- driver_unregister(&ohci_hcd_au1xxx_driver);
+ platform_driver_unregister(&ohci_hcd_au1xxx_driver);
}
module_init (ohci_hcd_au1xxx_init);
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
index 336c766..3959ccc 100644
--- a/drivers/usb/host/ohci-lh7a404.c
+++ b/drivers/usb/host/ohci-lh7a404.c
@@ -204,9 +204,8 @@ static const struct hc_driver ohci_lh7a404_hc_driver = {
/*-------------------------------------------------------------------------*/
-static int ohci_hcd_lh7a404_drv_probe(struct device *dev)
+static int ohci_hcd_lh7a404_drv_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
int ret;
pr_debug ("In ohci_hcd_lh7a404_drv_probe");
@@ -218,40 +217,38 @@ static int ohci_hcd_lh7a404_drv_probe(struct device *dev)
return ret;
}
-static int ohci_hcd_lh7a404_drv_remove(struct device *dev)
+static int ohci_hcd_lh7a404_drv_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_hcd_lh7a404_remove(hcd, pdev);
return 0;
}
/*TBD*/
-/*static int ohci_hcd_lh7a404_drv_suspend(struct device *dev)
+/*static int ohci_hcd_lh7a404_drv_suspend(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
return 0;
}
-static int ohci_hcd_lh7a404_drv_resume(struct device *dev)
+static int ohci_hcd_lh7a404_drv_resume(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
return 0;
}
*/
-static struct device_driver ohci_hcd_lh7a404_driver = {
- .name = "lh7a404-ohci",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver ohci_hcd_lh7a404_driver = {
.probe = ohci_hcd_lh7a404_drv_probe,
.remove = ohci_hcd_lh7a404_drv_remove,
/*.suspend = ohci_hcd_lh7a404_drv_suspend, */
/*.resume = ohci_hcd_lh7a404_drv_resume, */
+ .driver = {
+ .name = "lh7a404-ohci",
+ .owner = THIS_MODULE,
+ },
};
static int __init ohci_hcd_lh7a404_init (void)
@@ -260,12 +257,12 @@ static int __init ohci_hcd_lh7a404_init (void)
pr_debug ("block sizes: ed %d td %d\n",
sizeof (struct ed), sizeof (struct td));
- return driver_register(&ohci_hcd_lh7a404_driver);
+ return platform_driver_register(&ohci_hcd_lh7a404_driver);
}
static void __exit ohci_hcd_lh7a404_cleanup (void)
{
- driver_unregister(&ohci_hcd_lh7a404_driver);
+ platform_driver_unregister(&ohci_hcd_lh7a404_driver);
}
module_init (ohci_hcd_lh7a404_init);
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index e46cc54..c9e29d8 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -433,24 +433,22 @@ static const struct hc_driver ohci_omap_hc_driver = {
/*-------------------------------------------------------------------------*/
-static int ohci_hcd_omap_drv_probe(struct device *dev)
+static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
{
- return usb_hcd_omap_probe(&ohci_omap_hc_driver,
- to_platform_device(dev));
+ return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
}
-static int ohci_hcd_omap_drv_remove(struct device *dev)
+static int ohci_hcd_omap_drv_remove(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- usb_hcd_omap_remove(hcd, pdev);
+ usb_hcd_omap_remove(hcd, dev);
if (ohci->transceiver) {
(void) otg_set_host(ohci->transceiver, 0);
put_device(ohci->transceiver->dev);
}
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
return 0;
}
@@ -459,9 +457,9 @@ static int ohci_hcd_omap_drv_remove(struct device *dev)
#ifdef CONFIG_PM
-static int ohci_omap_suspend(struct device *dev, pm_message_t message)
+static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message)
{
- struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev));
+ struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev));
if (time_before(jiffies, ohci->next_statechange))
msleep(5);
@@ -473,9 +471,9 @@ static int ohci_omap_suspend(struct device *dev, pm_message_t message)
return 0;
}
-static int ohci_omap_resume(struct device *dev)
+static int ohci_omap_resume(struct platform_device *dev)
{
- struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev));
+ struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev));
if (time_before(jiffies, ohci->next_statechange))
msleep(5);
@@ -494,16 +492,17 @@ static int ohci_omap_resume(struct device *dev)
/*
* Driver definition to register with the OMAP bus
*/
-static struct device_driver ohci_hcd_omap_driver = {
- .name = "ohci",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver ohci_hcd_omap_driver = {
.probe = ohci_hcd_omap_drv_probe,
.remove = ohci_hcd_omap_drv_remove,
#ifdef CONFIG_PM
.suspend = ohci_omap_suspend,
.resume = ohci_omap_resume,
#endif
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ohci",
+ },
};
static int __init ohci_hcd_omap_init (void)
@@ -515,12 +514,12 @@ static int __init ohci_hcd_omap_init (void)
pr_debug("%s: block sizes: ed %Zd td %Zd\n", hcd_name,
sizeof (struct ed), sizeof (struct td));
- return driver_register(&ohci_hcd_omap_driver);
+ return platform_driver_register(&ohci_hcd_omap_driver);
}
static void __exit ohci_hcd_omap_cleanup (void)
{
- driver_unregister(&ohci_hcd_omap_driver);
+ platform_driver_unregister(&ohci_hcd_omap_driver);
}
module_init (ohci_hcd_omap_init);
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 7ce1d9e..a59e536 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -218,7 +218,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
static struct pci_driver ohci_pci_driver = {
.name = (char *) hcd_name,
.id_table = pci_ids,
- .owner = THIS_MODULE,
.probe = usb_hcd_pci_probe,
.remove = usb_hcd_pci_remove,
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
index 92cf6f4a..2ec6a78 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -172,9 +172,8 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = {
.start_port_reset = ohci_start_port_reset,
};
-static int ohci_hcd_ppc_soc_drv_probe(struct device *dev)
+static int ohci_hcd_ppc_soc_drv_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
int ret;
if (usb_disabled())
@@ -184,25 +183,25 @@ static int ohci_hcd_ppc_soc_drv_probe(struct device *dev)
return ret;
}
-static int ohci_hcd_ppc_soc_drv_remove(struct device *dev)
+static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_hcd_ppc_soc_remove(hcd, pdev);
return 0;
}
-static struct device_driver ohci_hcd_ppc_soc_driver = {
- .name = "ppc-soc-ohci",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver ohci_hcd_ppc_soc_driver = {
.probe = ohci_hcd_ppc_soc_drv_probe,
.remove = ohci_hcd_ppc_soc_drv_remove,
#ifdef CONFIG_PM
/*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/
/*.resume = ohci_hcd_ppc_soc_drv_resume,*/
#endif
+ .driver = {
+ .name = "ppc-soc-ohci",
+ .owner = THIS_MODULE,
+ },
};
static int __init ohci_hcd_ppc_soc_init(void)
@@ -211,12 +210,12 @@ static int __init ohci_hcd_ppc_soc_init(void)
pr_debug("block sizes: ed %d td %d\n", sizeof(struct ed),
sizeof(struct td));
- return driver_register(&ohci_hcd_ppc_soc_driver);
+ return platform_driver_register(&ohci_hcd_ppc_soc_driver);
}
static void __exit ohci_hcd_ppc_soc_cleanup(void)
{
- driver_unregister(&ohci_hcd_ppc_soc_driver);
+ platform_driver_unregister(&ohci_hcd_ppc_soc_driver);
}
module_init(ohci_hcd_ppc_soc_init);
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 59e2056..9d65ec3 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -290,9 +290,8 @@ static const struct hc_driver ohci_pxa27x_hc_driver = {
/*-------------------------------------------------------------------------*/
-static int ohci_hcd_pxa27x_drv_probe(struct device *dev)
+static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
int ret;
pr_debug ("In ohci_hcd_pxa27x_drv_probe");
@@ -304,41 +303,39 @@ static int ohci_hcd_pxa27x_drv_probe(struct device *dev)
return ret;
}
-static int ohci_hcd_pxa27x_drv_remove(struct device *dev)
+static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_hcd_pxa27x_remove(hcd, pdev);
return 0;
}
-static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state)
+static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *dev, pm_message_t state)
{
-// struct platform_device *pdev = to_platform_device(dev);
-// struct usb_hcd *hcd = dev_get_drvdata(dev);
+// struct usb_hcd *hcd = platform_get_drvdata(dev);
printk("%s: not implemented yet\n", __FUNCTION__);
return 0;
}
-static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
+static int ohci_hcd_pxa27x_drv_resume(struct platform_device *dev)
{
-// struct platform_device *pdev = to_platform_device(dev);
-// struct usb_hcd *hcd = dev_get_drvdata(dev);
+// struct usb_hcd *hcd = platform_get_drvdata(dev);
printk("%s: not implemented yet\n", __FUNCTION__);
return 0;
}
-static struct device_driver ohci_hcd_pxa27x_driver = {
- .name = "pxa27x-ohci",
- .bus = &platform_bus_type,
+static struct platform_driver ohci_hcd_pxa27x_driver = {
.probe = ohci_hcd_pxa27x_drv_probe,
.remove = ohci_hcd_pxa27x_drv_remove,
.suspend = ohci_hcd_pxa27x_drv_suspend,
- .resume = ohci_hcd_pxa27x_drv_resume,
+ .resume = ohci_hcd_pxa27x_drv_resume,
+ .driver = {
+ .name = "pxa27x-ohci",
+ },
};
static int __init ohci_hcd_pxa27x_init (void)
@@ -347,12 +344,12 @@ static int __init ohci_hcd_pxa27x_init (void)
pr_debug ("block sizes: ed %d td %d\n",
sizeof (struct ed), sizeof (struct td));
- return driver_register(&ohci_hcd_pxa27x_driver);
+ return platform_driver_register(&ohci_hcd_pxa27x_driver);
}
static void __exit ohci_hcd_pxa27x_cleanup (void)
{
- driver_unregister(&ohci_hcd_pxa27x_driver);
+ platform_driver_unregister(&ohci_hcd_pxa27x_driver);
}
module_init (ohci_hcd_pxa27x_init);
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index ee1fc60..35cc940 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -459,39 +459,38 @@ static const struct hc_driver ohci_s3c2410_hc_driver = {
/* device driver */
-static int ohci_hcd_s3c2410_drv_probe(struct device *dev)
+static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev);
}
-static int ohci_hcd_s3c2410_drv_remove(struct device *dev)
+static int ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_hcd_s3c2410_remove(hcd, pdev);
return 0;
}
-static struct device_driver ohci_hcd_s3c2410_driver = {
- .name = "s3c2410-ohci",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver ohci_hcd_s3c2410_driver = {
.probe = ohci_hcd_s3c2410_drv_probe,
.remove = ohci_hcd_s3c2410_drv_remove,
/*.suspend = ohci_hcd_s3c2410_drv_suspend, */
/*.resume = ohci_hcd_s3c2410_drv_resume, */
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s3c2410-ohci",
+ },
};
static int __init ohci_hcd_s3c2410_init (void)
{
- return driver_register(&ohci_hcd_s3c2410_driver);
+ return platform_driver_register(&ohci_hcd_s3c2410_driver);
}
static void __exit ohci_hcd_s3c2410_cleanup (void)
{
- driver_unregister(&ohci_hcd_s3c2410_driver);
+ platform_driver_unregister(&ohci_hcd_s3c2410_driver);
}
module_init (ohci_hcd_s3c2410_init);
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 5607c0a..a7722a6 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1631,24 +1631,21 @@ static struct hc_driver sl811h_hc_driver = {
/*-------------------------------------------------------------------------*/
static int __devexit
-sl811h_remove(struct device *dev)
+sl811h_remove(struct platform_device *dev)
{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
struct sl811 *sl811 = hcd_to_sl811(hcd);
- struct platform_device *pdev;
struct resource *res;
- pdev = container_of(dev, struct platform_device, dev);
-
remove_debug_file(sl811);
usb_remove_hcd(hcd);
/* some platforms may use IORESOURCE_IO */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ res = platform_get_resource(dev, IORESOURCE_MEM, 1);
if (res)
iounmap(sl811->data_reg);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (res)
iounmap(sl811->addr_reg);
@@ -1657,11 +1654,10 @@ sl811h_remove(struct device *dev)
}
static int __devinit
-sl811h_probe(struct device *dev)
+sl811h_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
struct sl811 *sl811;
- struct platform_device *pdev;
struct resource *addr, *data;
int irq;
void __iomem *addr_reg;
@@ -1674,24 +1670,23 @@ sl811h_probe(struct device *dev)
* specific platform_data. we don't probe for IRQs, and do only
* minimal sanity checking.
*/
- pdev = container_of(dev, struct platform_device, dev);
- irq = platform_get_irq(pdev, 0);
- if (pdev->num_resources < 3 || irq < 0)
+ irq = platform_get_irq(dev, 0);
+ if (dev->num_resources < 3 || irq < 0)
return -ENODEV;
/* refuse to confuse usbcore */
- if (dev->dma_mask) {
+ if (dev->dev.dma_mask) {
DBG("no we won't dma\n");
return -EINVAL;
}
/* the chip may be wired for either kind of addressing */
- addr = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- data = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ addr = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ data = platform_get_resource(dev, IORESOURCE_MEM, 1);
retval = -EBUSY;
if (!addr || !data) {
- addr = platform_get_resource(pdev, IORESOURCE_IO, 0);
- data = platform_get_resource(pdev, IORESOURCE_IO, 1);
+ addr = platform_get_resource(dev, IORESOURCE_IO, 0);
+ data = platform_get_resource(dev, IORESOURCE_IO, 1);
if (!addr || !data)
return -ENODEV;
ioaddr = 1;
@@ -1713,7 +1708,7 @@ sl811h_probe(struct device *dev)
}
/* allocate and initialize hcd */
- hcd = usb_create_hcd(&sl811h_hc_driver, dev, dev->bus_id);
+ hcd = usb_create_hcd(&sl811h_hc_driver, &dev->dev, dev->dev.bus_id);
if (!hcd) {
retval = -ENOMEM;
goto err5;
@@ -1723,7 +1718,7 @@ sl811h_probe(struct device *dev)
spin_lock_init(&sl811->lock);
INIT_LIST_HEAD(&sl811->async);
- sl811->board = dev->platform_data;
+ sl811->board = dev->dev.platform_data;
init_timer(&sl811->timer);
sl811->timer.function = sl811h_timer;
sl811->timer.data = (unsigned long) sl811;
@@ -1785,9 +1780,9 @@ sl811h_probe(struct device *dev)
*/
static int
-sl811h_suspend(struct device *dev, pm_message_t state)
+sl811h_suspend(struct platform_device *dev, pm_message_t state)
{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
struct sl811 *sl811 = hcd_to_sl811(hcd);
int retval = 0;
@@ -1796,27 +1791,27 @@ sl811h_suspend(struct device *dev, pm_message_t state)
else if (state.event == PM_EVENT_SUSPEND)
port_power(sl811, 0);
if (retval == 0)
- dev->power.power_state = state;
+ dev->dev.power.power_state = state;
return retval;
}
static int
-sl811h_resume(struct device *dev)
+sl811h_resume(struct platform_device *dev)
{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
struct sl811 *sl811 = hcd_to_sl811(hcd);
/* with no "check to see if VBUS is still powered" board hook,
* let's assume it'd only be powered to enable remote wakeup.
*/
- if (dev->power.power_state.event == PM_EVENT_SUSPEND
+ if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND
|| !hcd->can_wakeup) {
sl811->port1 = 0;
port_power(sl811, 1);
return 0;
}
- dev->power.power_state = PMSG_ON;
+ dev->dev.power.power_state = PMSG_ON;
return sl811h_bus_resume(hcd);
}
@@ -1829,16 +1824,16 @@ sl811h_resume(struct device *dev)
/* this driver is exported so sl811_cs can depend on it */
-struct device_driver sl811h_driver = {
- .name = (char *) hcd_name,
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
-
+struct platform_driver sl811h_driver = {
.probe = sl811h_probe,
.remove = __devexit_p(sl811h_remove),
.suspend = sl811h_suspend,
.resume = sl811h_resume,
+ .driver = {
+ .name = (char *) hcd_name,
+ .owner = THIS_MODULE,
+ },
};
EXPORT_SYMBOL(sl811h_driver);
@@ -1850,12 +1845,12 @@ static int __init sl811h_init(void)
return -ENODEV;
INFO("driver %s, %s\n", hcd_name, DRIVER_VERSION);
- return driver_register(&sl811h_driver);
+ return platform_driver_register(&sl811h_driver);
}
module_init(sl811h_init);
static void __exit sl811h_cleanup(void)
{
- driver_unregister(&sl811h_driver);
+ platform_driver_unregister(&sl811h_driver);
}
module_exit(sl811h_cleanup);
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 15e0a51..d33ce39 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -831,7 +831,6 @@ MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
static struct pci_driver uhci_pci_driver = {
.name = (char *)hcd_name,
.id_table = uhci_pci_ids,
- .owner = THIS_MODULE,
.probe = usb_hcd_pci_probe,
.remove = usb_hcd_pci_remove,
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index c89d076..950543a 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -327,6 +327,18 @@ static inline void mts_urb_abort(struct mts_desc* desc) {
usb_kill_urb( desc->urb );
}
+static int mts_slave_alloc (struct scsi_device *s)
+{
+ s->inquiry_len = 0x24;
+ return 0;
+}
+
+static int mts_slave_configure (struct scsi_device *s)
+{
+ blk_queue_dma_alignment(s->request_queue, (512 - 1));
+ return 0;
+}
+
static int mts_scsi_abort (Scsi_Cmnd *srb)
{
struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
@@ -411,7 +423,7 @@ static void mts_transfer_done( struct urb *transfer, struct pt_regs *regs )
MTS_INT_INIT();
context->srb->result &= MTS_SCSI_ERR_MASK;
- context->srb->result |= (unsigned)context->status<<1;
+ context->srb->result |= (unsigned)(*context->scsi_status)<<1;
mts_transfer_cleanup(transfer);
@@ -427,7 +439,7 @@ static void mts_get_status( struct urb *transfer )
mts_int_submit_urb(transfer,
usb_rcvbulkpipe(context->instance->usb_dev,
context->instance->ep_response),
- &context->status,
+ context->scsi_status,
1,
mts_transfer_done );
}
@@ -481,7 +493,7 @@ static void mts_command_done( struct urb *transfer, struct pt_regs *regs )
context->data_pipe,
context->data,
context->data_length,
- context->srb->use_sg ? mts_do_sg : mts_data_done);
+ context->srb->use_sg > 1 ? mts_do_sg : mts_data_done);
} else {
mts_get_status(transfer);
}
@@ -627,12 +639,11 @@ int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback )
callback(srb);
}
-
out:
return err;
}
-static Scsi_Host_Template mts_scsi_host_template = {
+static struct scsi_host_template mts_scsi_host_template = {
.module = THIS_MODULE,
.name = "microtekX6",
.proc_name = "microtekX6",
@@ -645,6 +656,9 @@ static Scsi_Host_Template mts_scsi_host_template = {
.cmd_per_lun = 1,
.use_clustering = 1,
.emulated = 1,
+ .slave_alloc = mts_slave_alloc,
+ .slave_configure = mts_slave_configure,
+ .max_sectors= 256, /* 128 K */
};
struct vendor_product
@@ -771,8 +785,8 @@ static int mts_usb_probe(struct usb_interface *intf,
MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" );
return -ENODEV;
}
-
-
+
+
new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL);
if (!new_desc)
goto out;
@@ -781,6 +795,10 @@ static int mts_usb_probe(struct usb_interface *intf,
if (!new_desc->urb)
goto out_kfree;
+ new_desc->context.scsi_status = kmalloc(1, GFP_KERNEL);
+ if (!new_desc->context.scsi_status)
+ goto out_kfree2;
+
new_desc->usb_dev = dev;
new_desc->usb_intf = intf;
init_MUTEX(&new_desc->lock);
@@ -817,6 +835,8 @@ static int mts_usb_probe(struct usb_interface *intf,
usb_set_intfdata(intf, new_desc);
return 0;
+ out_kfree2:
+ kfree(new_desc->context.scsi_status);
out_free_urb:
usb_free_urb(new_desc->urb);
out_kfree:
@@ -836,6 +856,7 @@ static void mts_usb_disconnect (struct usb_interface *intf)
scsi_host_put(desc->host);
usb_free_urb(desc->urb);
+ kfree(desc->context.scsi_status);
kfree(desc);
}
@@ -856,5 +877,3 @@ module_exit(microtek_drv_exit);
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");
-
-
diff --git a/drivers/usb/image/microtek.h b/drivers/usb/image/microtek.h
index 3271deb..926d4bd 100644
--- a/drivers/usb/image/microtek.h
+++ b/drivers/usb/image/microtek.h
@@ -22,7 +22,7 @@ struct mts_transfer_context
int data_pipe;
int fragment;
- u8 status; /* status returned from ep_response after command completion */
+ u8 *scsi_status; /* status returned from ep_response after command completion */
};
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index 5e03b93..07cb17d 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -42,3 +42,7 @@ obj-$(CONFIG_USB_ACECAD) += acecad.o
obj-$(CONFIG_USB_YEALINK) += yealink.o
obj-$(CONFIG_USB_XPAD) += xpad.o
obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o
+
+ifeq ($(CONFIG_USB_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 79ddce4..45f3130 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1318,6 +1318,7 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_WACOM_PTU 0x0003
#define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0
#define USB_DEVICE_ID_WACOM_CINTIQ 0x003F
+#define USB_DEVICE_ID_WACOM_DTF 0x00C0
#define USB_VENDOR_ID_ACECAD 0x0460
#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004
@@ -1524,6 +1525,9 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 3, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 4, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 5, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 7, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 8, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 9, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 1, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE },
@@ -1531,11 +1535,19 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 5, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 1, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 2, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 3, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 4, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 5, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 6, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 5, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c
index 3b58185..4a50acb 100644
--- a/drivers/usb/input/itmtouch.c
+++ b/drivers/usb/input/itmtouch.c
@@ -40,13 +40,6 @@
*****************************************************************************/
#include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
-
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/input.h>
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index 5b8d65f..a32cfe5 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -160,7 +160,8 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
* though so it's not too big a deal
*/
if (dev->data.pos >= dev->data.len) {
- dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n",
+ dev_dbg(&dev->udev->dev,
+ "%s - Error ran out of data. pos: %d, len: %d\n",
__FUNCTION__, dev->data.pos, dev->data.len);
return -1;
}
@@ -306,7 +307,7 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs)
err("Bad message recieved, no stop bit found.\n");
}
- dev_dbg(&remote->udev,
+ dev_dbg(&remote->udev->dev,
"%s found valid message: system: %d, button: %d, toggle: %d\n",
__FUNCTION__, message.system, message.button, message.toggle);
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
index 7fce526..52cc18c 100644
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -40,13 +40,6 @@
*****************************************************************************/
#include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
-
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/input.h>
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
index dca5ee9..19e015d 100644
--- a/drivers/usb/input/pid.c
+++ b/drivers/usb/input/pid.c
@@ -37,8 +37,6 @@
#include "hid.h"
#include "pid.h"
-#define DEBUG
-
#define CHECK_OWNERSHIP(i, hid_pid) \
((i) < FF_EFFECTS_MAX && i >= 0 && \
test_bit(FF_PID_FLAGS_USED, &hid_pid->effects[(i)].flags) && \
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
index 0043e6e..7420c6b 100644
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -30,10 +30,6 @@
#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>
-
-#if !defined(DEBUG) && defined(CONFIG_USB_DEBUG)
-#define DEBUG
-#endif
#include <linux/usb.h>
#include <linux/usb_input.h>
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
index ea0f757..aea1cfa 100644
--- a/drivers/usb/input/wacom.c
+++ b/drivers/usb/input/wacom.c
@@ -52,8 +52,10 @@
* v1.30.1 (pi) - Added Graphire3 support
* v1.40 (pc) - Add support for several new devices, fix eraser reporting, ...
* v1.43 (pc) - Added support for Cintiq 21UX
- - Fixed a Graphire bug
- - Merged wacom_intuos3_irq into wacom_intuos_irq
+ * - Fixed a Graphire bug
+ * - Merged wacom_intuos3_irq into wacom_intuos_irq
+ * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc.
+ * - Report Device IDs
*/
/*
@@ -76,7 +78,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.43"
+#define DRIVER_VERSION "v1.44"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
#define DRIVER_LICENSE "GPL"
@@ -86,10 +88,14 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE(DRIVER_LICENSE);
#define USB_VENDOR_ID_WACOM 0x056a
+#define STYLUS_DEVICE_ID 0x02
+#define CURSOR_DEVICE_ID 0x06
+#define ERASER_DEVICE_ID 0x0A
enum {
PENPARTNER = 0,
GRAPHIRE,
+ G4,
PL,
INTUOS,
INTUOS3,
@@ -116,6 +122,7 @@ struct wacom {
struct urb *irq;
struct wacom_features *features;
int tool[2];
+ int id[2];
__u32 serial[2];
char phys[32];
};
@@ -136,7 +143,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
struct wacom *wacom = urb->context;
unsigned char *data = wacom->data;
struct input_dev *dev = wacom->dev;
- int prox, pressure;
+ int prox, pressure, id;
int retval;
switch (urb->status) {
@@ -163,6 +170,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
input_regs(dev, regs);
+ id = ERASER_DEVICE_ID;
if (prox) {
pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
@@ -177,11 +185,15 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
* an out of proximity for previous tool then a in for new tool.
*/
if (!wacom->tool[0]) {
- /* Going into proximity select tool */
- wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+ /* Eraser bit set for DTF */
+ if (data[1] & 0x10)
+ wacom->tool[1] = BTN_TOOL_RUBBER;
+ else
+ /* Going into proximity select tool */
+ wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
} else {
/* was entered with stylus2 pressed */
- if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) {
+ if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) {
/* report out proximity for previous tool */
input_report_key(dev, wacom->tool[1], 0);
input_sync(dev);
@@ -192,8 +204,9 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
if (wacom->tool[1] != BTN_TOOL_RUBBER) {
/* Unknown tool selected default to pen tool */
wacom->tool[1] = BTN_TOOL_PEN;
+ id = STYLUS_DEVICE_ID;
}
- input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */
+ input_report_key(dev, wacom->tool[1], id); /* report in proximity for tool */
input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
input_report_abs(dev, ABS_PRESSURE, pressure);
@@ -250,10 +263,10 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
input_regs(dev, regs);
if (data[1] & 0x04) {
- input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20);
+ input_report_key(dev, BTN_TOOL_RUBBER, (data[1] & 0x20) ? ERASER_DEVICE_ID : 0);
input_report_key(dev, BTN_TOUCH, data[1] & 0x08);
} else {
- input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20);
+ input_report_key(dev, BTN_TOOL_PEN, (data[1] & 0x20) ? STYLUS_DEVICE_ID : 0);
input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
}
input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2]));
@@ -299,7 +312,7 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs)
}
input_regs(dev, regs);
- input_report_key(dev, BTN_TOOL_PEN, 1);
+ input_report_key(dev, BTN_TOOL_PEN, STYLUS_DEVICE_ID);
input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1]));
input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3]));
input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127);
@@ -319,7 +332,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
struct wacom *wacom = urb->context;
unsigned char *data = wacom->data;
struct input_dev *dev = wacom->dev;
- int x, y;
+ int x, y, id, rw;
int retval;
switch (urb->status) {
@@ -344,6 +357,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
input_regs(dev, regs);
+ id = STYLUS_DEVICE_ID;
if (data[1] & 0x10) { /* in prox */
switch ((data[1] >> 5) & 3) {
@@ -354,18 +368,27 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
case 1: /* Rubber */
wacom->tool[0] = BTN_TOOL_RUBBER;
+ id = ERASER_DEVICE_ID;
break;
case 2: /* Mouse with wheel */
input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
- input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
+ if (wacom->features->type == G4) {
+ rw = data[7] & 0x04 ? -(data[7] & 0x03) : (data[7] & 0x03);
+ input_report_rel(dev, REL_WHEEL, rw);
+ } else
+ input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
/* fall through */
case 3: /* Mouse without wheel */
wacom->tool[0] = BTN_TOOL_MOUSE;
+ id = CURSOR_DEVICE_ID;
input_report_key(dev, BTN_LEFT, data[1] & 0x01);
input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
- input_report_abs(dev, ABS_DISTANCE, data[7]);
+ if (wacom->features->type == G4)
+ input_report_abs(dev, ABS_DISTANCE, data[6]);
+ else
+ input_report_abs(dev, ABS_DISTANCE, data[7]);
break;
}
}
@@ -376,16 +399,50 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
input_report_abs(dev, ABS_X, x);
input_report_abs(dev, ABS_Y, y);
if (wacom->tool[0] != BTN_TOOL_MOUSE) {
- input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6]));
+ input_report_abs(dev, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8));
input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
}
}
- input_report_key(dev, wacom->tool[0], data[1] & 0x10);
+ input_report_key(dev, wacom->tool[0], (data[1] & 0x10) ? id : 0);
input_sync(dev);
+ /* send pad data */
+ if (wacom->features->type == G4) {
+ /* fist time sending pad data */
+ if (wacom->tool[1] != BTN_TOOL_FINGER) {
+ wacom->id[1] = 0;
+ wacom->serial[1] = (data[7] & 0x38) >> 2;
+ }
+ if (data[7] & 0xf8) {
+ input_report_key(dev, BTN_0, (data[7] & 0x40));
+ input_report_key(dev, BTN_4, (data[7] & 0x80));
+ if (((data[7] & 0x38) >> 2) == (wacom->serial[1] & 0x0e))
+ /* alter REL_WHEEL value so X apps can get it */
+ wacom->serial[1] += (wacom->serial[1] & 0x01) ? -1 : 1;
+ else
+ wacom->serial[1] = (data[7] & 0x38 ) >> 2;
+
+ /* don't alter the value when there is no wheel event */
+ if (wacom->serial[1] == 1)
+ wacom->serial[1] = 0;
+ rw = wacom->serial[1];
+ rw = (rw & 0x08) ? -(rw & 0x07) : (rw & 0x07);
+ input_report_rel(dev, REL_WHEEL, rw);
+ wacom->tool[1] = BTN_TOOL_FINGER;
+ wacom->id[1] = data[7] & 0xf8;
+ input_report_key(dev, wacom->tool[1], 0xf0);
+ input_event(dev, EV_MSC, MSC_SERIAL, 0xf0);
+ } else if (wacom->id[1]) {
+ wacom->id[1] = 0;
+ wacom->serial[1] = 0;
+ input_report_key(dev, wacom->tool[1], 0);
+ input_event(dev, EV_MSC, MSC_SERIAL, 0xf0);
+ }
+ input_sync(dev);
+ }
exit:
retval = usb_submit_urb (urb, GFP_ATOMIC);
if (retval)
@@ -410,7 +467,8 @@ static int wacom_intuos_inout(struct urb *urb)
(data[4] << 20) + (data[5] << 12) +
(data[6] << 4) + (data[7] >> 4);
- switch ((data[2] << 4) | (data[3] >> 4)) {
+ wacom->id[idx] = (data[2] << 4) | (data[3] >> 4);
+ switch (wacom->id[idx]) {
case 0x812: /* Inking pen */
case 0x801: /* Intuos3 Inking pen */
case 0x012:
@@ -458,7 +516,7 @@ static int wacom_intuos_inout(struct urb *urb)
default: /* Unknown tool */
wacom->tool[idx] = BTN_TOOL_PEN;
}
- input_report_key(dev, wacom->tool[idx], 1);
+ input_report_key(dev, wacom->tool[idx], wacom->id[idx]);
input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
input_sync(dev);
return 1;
@@ -637,7 +695,7 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
}
}
- input_report_key(dev, wacom->tool[idx], 1);
+ input_report_key(dev, wacom->tool[idx], wacom->id[idx]);
input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
input_sync(dev);
@@ -655,6 +713,13 @@ static struct wacom_features wacom_features[] = {
{ "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq },
{ "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq },
{ "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq },
+ { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, G4, wacom_graphire_irq },
+ { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, G4, wacom_graphire_irq },
+ { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq },
+ { "Wacom PenStation2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_graphire_irq },
+ { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq },
+ { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 32, GRAPHIRE, wacom_graphire_irq },
+ { "Wacom PenPartner2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_graphire_irq },
{ "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq },
{ "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
{ "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq },
@@ -666,16 +731,20 @@ static struct wacom_features wacom_features[] = {
{ "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_pl_irq },
{ "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_pl_irq },
{ "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq },
+ { "Wacom PL700", 8, 6758, 5406, 511, 32, PL, wacom_pl_irq },
+ { "Wacom PL510", 8, 6282, 4762, 511, 32, PL, wacom_pl_irq },
+ { "Wacom PL710", 8, 34080, 27660, 511, 32, PL, wacom_pl_irq },
+ { "Wacom DTF720", 8, 6858, 5506, 511, 32, PL, wacom_pl_irq },
+ { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq },
{ "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq },
{ "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
{ "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq },
{ "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
{ "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
- { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq },
- { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq },
{ "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq },
{ "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq },
{ "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq },
+ { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 15, INTUOS3, wacom_intuos_irq },
{ "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq },
{ "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
{ }
@@ -688,6 +757,13 @@ static struct usb_device_id wacom_ids[] = {
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) },
@@ -699,16 +775,20 @@ static struct usb_device_id wacom_ids[] = {
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
{ }
@@ -779,6 +859,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0);
switch (wacom->features->type) {
+ case G4:
+ input_dev->evbit[0] |= BIT(EV_MSC);
+ input_dev->mscbit[0] |= BIT(MSC_SERIAL);
+ input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
+ input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
+ /* fall through */
+
case GRAPHIRE:
input_dev->evbit[0] |= BIT(EV_REL);
input_dev->relbit[0] |= BIT(REL_WHEEL);
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 862e40a..6c693bc 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -18,4 +18,8 @@ obj-$(CONFIG_USB_RIO500) += rio500.o
obj-$(CONFIG_USB_TEST) += usbtest.o
obj-$(CONFIG_USB_USS720) += uss720.o
-obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ \ No newline at end of file
+obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/
+
+ifeq ($(CONFIG_USB_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index 5f33f7c..2a28cee 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -30,7 +30,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/wait.h>
-#undef DEBUG /* include debug macros until it's done */
#include <linux/usb.h>
/*-------------------------------------------------------------------*/
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c
index b84eda6..a30d4a6 100644
--- a/drivers/usb/misc/phidgetservo.c
+++ b/drivers/usb/misc/phidgetservo.c
@@ -26,9 +26,6 @@
*/
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-#define DEBUG 1
-#endif
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index 7d02d8e..9590dba 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -393,7 +393,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
ibuf, this_read, &partial,
8000);
- dbg(KERN_DEBUG "read stats: result:%d this_read:%u partial:%u",
+ dbg("read stats: result:%d this_read:%u partial:%u",
result, this_read, partial);
if (partial) {
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c
index f6ba4c7..3c93921 100644
--- a/drivers/usb/misc/usbled.c
+++ b/drivers/usb/misc/usbled.c
@@ -10,9 +10,6 @@
*/
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG 1
-#endif
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 2997f558..605a2af 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -1,7 +1,4 @@
#include <linux/config.h>
-#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
-# define DEBUG
-#endif
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index 0592cb5..1cabe7e 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -41,8 +41,6 @@
/*****************************************************************************/
-#define DEBUG
-
#include <linux/module.h>
#include <linux/socket.h>
#include <linux/parport.h>
diff --git a/drivers/usb/net/Makefile b/drivers/usb/net/Makefile
index 222c049..a21e6ea 100644
--- a/drivers/usb/net/Makefile
+++ b/drivers/usb/net/Makefile
@@ -16,3 +16,7 @@ obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o
obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o
obj-$(CONFIG_USB_USBNET) += usbnet.o
obj-$(CONFIG_USB_ZD1201) += zd1201.o
+
+ifeq ($(CONFIG_USB_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
index 252a34f..542120e 100644
--- a/drivers/usb/net/asix.c
+++ b/drivers/usb/net/asix.c
@@ -23,9 +23,6 @@
// #define VERBOSE // more; success messages
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-# define DEBUG
-#endif
#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/sched.h>
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c
index 652b04b..c008c98 100644
--- a/drivers/usb/net/cdc_ether.c
+++ b/drivers/usb/net/cdc_ether.c
@@ -21,9 +21,6 @@
// #define VERBOSE // more; success messages
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-# define DEBUG
-#endif
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init.h>
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c
index f1730b6..f05cfb8 100644
--- a/drivers/usb/net/cdc_subset.c
+++ b/drivers/usb/net/cdc_subset.c
@@ -18,9 +18,6 @@
*/
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-# define DEBUG
-#endif
#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/sched.h>
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c
index c0f263b..2455e9a 100644
--- a/drivers/usb/net/gl620a.c
+++ b/drivers/usb/net/gl620a.c
@@ -22,9 +22,6 @@
// #define VERBOSE // more; success messages
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-# define DEBUG
-#endif
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init.h>
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
index 6bef1be..b577651 100644
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -219,7 +219,6 @@ struct kaweth_device
__u32 status;
int end;
- int removed;
int suspend_lowmem_rx;
int suspend_lowmem_ctrl;
int linkstate;
@@ -699,6 +698,7 @@ static int kaweth_close(struct net_device *net)
usb_kill_urb(kaweth->irq_urb);
usb_kill_urb(kaweth->rx_urb);
+ usb_kill_urb(kaweth->tx_urb);
flush_scheduled_work();
@@ -750,13 +750,6 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
spin_lock(&kaweth->device_lock);
- if (kaweth->removed) {
- /* our device is undergoing disconnection - we bail out */
- spin_unlock(&kaweth->device_lock);
- dev_kfree_skb_irq(skb);
- return 0;
- }
-
kaweth_async_set_rx_mode(kaweth);
netif_stop_queue(net);
@@ -1136,10 +1129,6 @@ static void kaweth_disconnect(struct usb_interface *intf)
return;
}
netdev = kaweth->net;
- kaweth->removed = 1;
- usb_kill_urb(kaweth->irq_urb);
- usb_kill_urb(kaweth->rx_urb);
- usb_kill_urb(kaweth->tx_urb);
kaweth_dbg("Unregistering net device");
unregister_netdev(netdev);
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c
index cee55f8..b3799b1 100644
--- a/drivers/usb/net/net1080.c
+++ b/drivers/usb/net/net1080.c
@@ -21,9 +21,6 @@
// #define VERBOSE // more; success messages
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-# define DEBUG
-#endif
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init.h>
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
index 537eb18..683e3df 100644
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -28,8 +28,6 @@
* is out of the interrupt routine.
*/
-#undef DEBUG
-
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/usb/net/plusb.c b/drivers/usb/net/plusb.c
index 74c2b35..89856aa 100644
--- a/drivers/usb/net/plusb.c
+++ b/drivers/usb/net/plusb.c
@@ -21,9 +21,6 @@
// #define VERBOSE // more; success messages
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-# define DEBUG
-#endif
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init.h>
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c
index b5a925d..c0ecbab 100644
--- a/drivers/usb/net/rndis_host.c
+++ b/drivers/usb/net/rndis_host.c
@@ -21,9 +21,6 @@
// #define VERBOSE // more; success messages
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-# define DEBUG
-#endif
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init.h>
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index 74f05c9..362d690 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -34,9 +34,6 @@
// #define VERBOSE // more; success messages
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-# define DEBUG
-#endif
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init.h>
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c
index 5d4b7d5..680d139 100644
--- a/drivers/usb/net/zaurus.c
+++ b/drivers/usb/net/zaurus.c
@@ -21,9 +21,6 @@
// #define VERBOSE // more; success messages
#include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-# define DEBUG
-#endif
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init.h>
diff --git a/drivers/usb/serial/ChangeLog.old b/drivers/usb/serial/ChangeLog.history
index c1b2799..52c4f7b 100644
--- a/drivers/usb/serial/ChangeLog.old
+++ b/drivers/usb/serial/ChangeLog.history
@@ -400,7 +400,7 @@ visor.c Change Log comments:
(11/11/2001) gkh
Added support for the m125 devices, and added check to prevent oopses
- for Clié devices that lie about the number of ports they have.
+ for Clié devices that lie about the number of ports they have.
(08/30/2001) gkh
Added support for the Clie devices, both the 3.5 and 4.0 os versions.
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 7b5e8e4..14f55fd 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -62,6 +62,15 @@ config USB_SERIAL_AIRPRIME
To compile this driver as a module, choose M here: the
module will be called airprime.
+config USB_SERIAL_ANYDATA
+ tristate "USB AnyData CDMA Wireless Driver"
+ depends on USB_SERIAL
+ help
+ Say Y here if you want to use a AnyData CDMA device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called anydata.
+
config USB_SERIAL_BELKIN
tristate "USB Belkin and Peracom Single Port Serial Driver"
depends on USB_SERIAL
@@ -394,15 +403,6 @@ config USB_SERIAL_MCT_U232
To compile this driver as a module, choose M here: the
module will be called mct_u232.
-config USB_SERIAL_NOKIA_DKU2
- tristate "USB Nokia DKU2 Driver"
- depends on USB_SERIAL
- help
- Say Y here if you want to use a Nokia DKU2 device.
-
- To compile this driver as a module, choose M here: the
- module will be called nokia_dku2.
-
config USB_SERIAL_PL2303
tristate "USB Prolific 2303 Single Port Serial Driver"
depends on USB_SERIAL
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index 55fd461..f0b0442 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -12,6 +12,7 @@ usbserial-obj-$(CONFIG_USB_EZUSB) += ezusb.o
usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y)
obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o
+obj-$(CONFIG_USB_SERIAL_ANYDATA) += anydata.o
obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o
obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o
obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o
@@ -31,7 +32,6 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o
obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o
obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o
obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o
-obj-$(CONFIG_USB_SERIAL_NOKIA_DKU2) += nokia_dku2.o
obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o
obj-$(CONFIG_USB_SERIAL_OPTION) += option.o
obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
diff --git a/drivers/usb/serial/anydata.c b/drivers/usb/serial/anydata.c
new file mode 100644
index 0000000..18022a7
--- /dev/null
+++ b/drivers/usb/serial/anydata.c
@@ -0,0 +1,123 @@
+/*
+ * AnyData CDMA Serial USB driver
+ *
+ * Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "usb-serial.h"
+
+static struct usb_device_id id_table [] = {
+ { USB_DEVICE(0x16d5, 0x6501) }, /* AirData CDMA device */
+ { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+/* if overridden by the user, then use their value for the size of the
+ * read and write urbs */
+static int buffer_size;
+static int debug;
+
+static struct usb_driver anydata_driver = {
+ .owner = THIS_MODULE,
+ .name = "anydata",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
+static int anydata_open(struct usb_serial_port *port, struct file *filp)
+{
+ char *buffer;
+ int result = 0;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (buffer_size) {
+ /* override the default buffer sizes */
+ buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!buffer) {
+ dev_err(&port->dev, "%s - out of memory.\n",
+ __FUNCTION__);
+ return -ENOMEM;
+ }
+ kfree (port->read_urb->transfer_buffer);
+ port->read_urb->transfer_buffer = buffer;
+ port->read_urb->transfer_buffer_length = buffer_size;
+
+ buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!buffer) {
+ dev_err(&port->dev, "%s - out of memory.\n",
+ __FUNCTION__);
+ return -ENOMEM;
+ }
+ kfree (port->write_urb->transfer_buffer);
+ port->write_urb->transfer_buffer = buffer;
+ port->write_urb->transfer_buffer_length = buffer_size;
+ port->bulk_out_size = buffer_size;
+ }
+
+ /* Start reading from the device */
+ usb_fill_bulk_urb(port->read_urb, port->serial->dev,
+ usb_rcvbulkpipe(port->serial->dev,
+ port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ usb_serial_generic_write_bulk_callback, port);
+ result = usb_submit_urb(port->read_urb, GFP_KERNEL);
+ if (result)
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __FUNCTION__, result);
+
+ return result;
+}
+
+static struct usb_serial_driver anydata_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "anydata",
+ },
+ .id_table = id_table,
+ .num_interrupt_in = NUM_DONT_CARE,
+ .num_bulk_in = NUM_DONT_CARE,
+ .num_bulk_out = NUM_DONT_CARE,
+ .num_ports = 1,
+ .open = anydata_open,
+};
+
+static int __init anydata_init(void)
+{
+ int retval;
+
+ retval = usb_serial_register(&anydata_device);
+ if (retval)
+ return retval;
+ retval = usb_register(&anydata_driver);
+ if (retval)
+ usb_serial_deregister(&anydata_device);
+ return retval;
+}
+
+static void __exit anydata_exit(void)
+{
+ usb_deregister(&anydata_driver);
+ usb_serial_deregister(&anydata_device);
+}
+
+module_init(anydata_init);
+module_exit(anydata_exit);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+module_param(buffer_size, int, 0);
+MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers");
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index c5334dd..c978700 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -60,6 +60,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
{ USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
{ USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
+ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
{ } /* Terminating Entry */
};
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 8909208..53a47c3 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -309,6 +309,7 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *re
schedule_work(&port->work);
}
+EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
void usb_serial_generic_shutdown (struct usb_serial *serial)
{
diff --git a/drivers/usb/serial/nokia_dku2.c b/drivers/usb/serial/nokia_dku2.c
deleted file mode 100644
index fad01be..0000000
--- a/drivers/usb/serial/nokia_dku2.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Nokia DKU2 USB driver
- *
- * Copyright (C) 2004
- * Author: C Kemp
- *
- * This program is largely derived from work by the linux-usb group
- * and associated source files. Please see the usb/serial files for
- * individual credits and copyrights.
- *
- * 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.
- *
- * 20.09.2005 - Matthias Blaesing <matthias.blaesing@rwth-aachen.de>
- * Added short name to device structure to make driver load into kernel 2.6.13
- *
- * 20.09.2005 - Matthias Blaesing <matthias.blaesing@rwth-aachen.de>
- * Added usb_deregister to exit code - to allow remove and reinsert of module
- */
-
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-#include "usb-serial.h"
-
-
-#define NOKIA_VENDOR_ID 0x0421
-#define NOKIA7600_PRODUCT_ID 0x0400
-#define NOKIA6230_PRODUCT_ID 0x040f
-#define NOKIA6170_PRODUCT_ID 0x0416
-#define NOKIA6670_PRODUCT_ID 0x041d
-#define NOKIA6680_PRODUCT_ID 0x041e
-#define NOKIA6230i_PRODUCT_ID 0x0428
-
-#define NOKIA_AT_PORT 0x82
-#define NOKIA_FBUS_PORT 0x86
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.2"
-#define DRIVER_AUTHOR "C Kemp"
-#define DRIVER_DESC "Nokia DKU2 Driver"
-
-static struct usb_device_id id_table [] = {
- { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA7600_PRODUCT_ID) },
- { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230_PRODUCT_ID) },
- { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6170_PRODUCT_ID) },
- { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6670_PRODUCT_ID) },
- { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6680_PRODUCT_ID) },
- { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230i_PRODUCT_ID) },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-/* The only thing which makes this device different from a generic
- * device is that we have to set an alternative configuration to make
- * the relevant endpoints available. In 2.6 this is really easy... */
-static int nokia_probe(struct usb_serial *serial,
- const struct usb_device_id *id)
-{
- int retval = -ENODEV;
-
- if (serial->interface->altsetting[0].endpoint[0].desc.bEndpointAddress == NOKIA_AT_PORT) {
- /* the AT port */
- dev_info(&serial->dev->dev, "Nokia AT Port:\n");
- retval = 0;
- } else if (serial->interface->num_altsetting == 2 &&
- serial->interface->altsetting[1].endpoint[0].desc.bEndpointAddress == NOKIA_FBUS_PORT) {
- /* the FBUS port */
- dev_info(&serial->dev->dev, "Nokia FBUS Port:\n");
- usb_set_interface(serial->dev, 10, 1);
- retval = 0;
- }
-
- return retval;
-}
-
-static struct usb_driver nokia_driver = {
- .owner = THIS_MODULE,
- .name = "nokia_dku2",
- .probe = usb_serial_probe,
- .disconnect = usb_serial_disconnect,
- .id_table = id_table,
-};
-
-static struct usb_serial_driver nokia_serial_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "nokia_dku2",
- },
- .description = "Nokia 7600/6230(i)/6170/66x0 DKU2 driver",
- .id_table = id_table,
- .num_interrupt_in = 1,
- .num_bulk_in = 1,
- .num_bulk_out = 1,
- .num_ports = 1,
- .probe = nokia_probe,
-};
-
-static int __init nokia_init(void)
-{
- int retval;
-
- retval = usb_serial_register(&nokia_serial_driver);
- if (retval)
- return retval;
-
- retval = usb_register(&nokia_driver);
- if (retval) {
- usb_serial_deregister(&nokia_serial_driver);
- return retval;
- }
-
- info(DRIVER_VERSION " " DRIVER_AUTHOR);
- info(DRIVER_DESC);
-
- return retval;
-}
-
-static void __exit nokia_exit(void)
-{
- usb_deregister(&nokia_driver);
- usb_serial_deregister(&nokia_serial_driver);
-}
-
-module_init(nokia_init);
-module_exit(nokia_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 165c119..41a45a5 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -71,7 +71,9 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) },
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) },
{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) },
+ { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) },
+ { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) },
{ USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) },
{ USB_DEVICE( NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID ) },
{ } /* Terminating entry */
@@ -811,7 +813,9 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
u8 length = UART_STATE;
if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) &&
- (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65)) {
+ (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 ||
+ le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_SX1 ||
+ le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X75)) {
length = 1;
status_idx = 0;
}
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 7be9644..21d434d 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -54,7 +54,9 @@
#define SAMSUNG_PRODUCT_ID 0x8001
#define SIEMENS_VENDOR_ID 0x11f5
+#define SIEMENS_PRODUCT_ID_SX1 0x0001
#define SIEMENS_PRODUCT_ID_X65 0x0003
+#define SIEMENS_PRODUCT_ID_X75 0x0004
#define SYNTECH_VENDOR_ID 0x0745
#define SYNTECH_PRODUCT_ID 0x0001
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index 1a9679f..c41d64d 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -115,7 +115,7 @@ config USB_STORAGE_JUMPSHOT
config USB_STORAGE_ONETOUCH
bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)"
- depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL
+ depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL && !PM
help
Say Y here to include additional code to support the Maxtor OneTouch
USB hard drive's onetouch button.
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index 33c55a6..fea176d 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -853,7 +853,7 @@ static int usbat_identify_device(struct us_data *us,
rc = usbat_device_reset(us);
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
- msleep(25);
+ msleep(500);
/*
* In attempt to distinguish between HP CDRW's and Flash readers, we now
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 9e926a8..0a9858f 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -710,11 +710,6 @@ UNUSUAL_DEV( 0x0686, 0x4017, 0x0001, 0x0001,
"DIMAGE E223",
US_SC_SCSI, US_PR_DEVICE, NULL, 0 ),
-UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100,
- "Hagiwara",
- "FlashGate SmartMedia",
- US_SC_SCSI, US_PR_BULK, NULL, 0 ),
-
UNUSUAL_DEV( 0x0693, 0x0005, 0x0100, 0x0100,
"Hagiwara",
"Flashgate",
@@ -1008,6 +1003,11 @@ UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
*
*/
#ifdef CONFIG_USB_STORAGE_ONETOUCH
+ UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999,
+ "Maxtor",
+ "OneTouch External Harddrive",
+ US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
+ 0),
UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999,
"Maxtor",
"OneTouch External Harddrive",
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 193b482..750cebb 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -1279,7 +1279,7 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)
printk("acornfb: freed %dK memory\n", mb_freed);
}
-static int __init acornfb_probe(struct device *dev)
+static int __init acornfb_probe(struct platform_device *dev)
{
unsigned long size;
u_int h_sync, v_sync;
@@ -1292,7 +1292,7 @@ static int __init acornfb_probe(struct device *dev)
acornfb_init_fbinfo();
- current_par.dev = dev;
+ current_par.dev = &dev->dev;
if (current_par.montype == -1)
current_par.montype = acornfb_detect_monitortype();
@@ -1453,15 +1453,16 @@ static int __init acornfb_probe(struct device *dev)
return 0;
}
-static struct device_driver acornfb_driver = {
- .name = "acornfb",
- .bus = &platform_bus_type,
+static struct platform_driver acornfb_driver = {
.probe = acornfb_probe,
+ .driver = {
+ .name = "acornfb",
+ },
};
static int __init acornfb_init(void)
{
- return driver_register(&acornfb_driver);
+ return platform_driver_register(&acornfb_driver);
}
module_init(acornfb_init);
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index a1fc8bb..080db81 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -514,9 +514,8 @@ static struct fb_ops arcfb_ops = {
.fb_ioctl = arcfb_ioctl,
};
-static int __init arcfb_probe(struct device *device)
+static int __init arcfb_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(device);
struct fb_info *info;
int retval = -ENOMEM;
int videomemorysize;
@@ -559,7 +558,7 @@ static int __init arcfb_probe(struct device *device)
retval = register_framebuffer(info);
if (retval < 0)
goto err1;
- dev_set_drvdata(&dev->dev, info);
+ platform_set_drvdata(dev, info);
if (irq) {
par->irq = irq;
if (request_irq(par->irq, &arcfb_interrupt, SA_SHIRQ,
@@ -600,9 +599,9 @@ err:
return retval;
}
-static int arcfb_remove(struct device *device)
+static int arcfb_remove(struct platform_device *dev)
{
- struct fb_info *info = dev_get_drvdata(device);
+ struct fb_info *info = platform_get_drvdata(dev);
if (info) {
unregister_framebuffer(info);
@@ -612,11 +611,12 @@ static int arcfb_remove(struct device *device)
return 0;
}
-static struct device_driver arcfb_driver = {
- .name = "arcfb",
- .bus = &platform_bus_type,
+static struct platform_driver arcfb_driver = {
.probe = arcfb_probe,
.remove = arcfb_remove,
+ .driver = {
+ .name = "arcfb",
+ },
};
static struct platform_device *arcfb_device;
@@ -628,7 +628,7 @@ static int __init arcfb_init(void)
if (!arcfb_enable)
return -ENXIO;
- ret = driver_register(&arcfb_driver);
+ ret = platform_driver_register(&arcfb_driver);
if (!ret) {
arcfb_device = platform_device_alloc("arcfb", 0);
if (arcfb_device) {
@@ -638,7 +638,7 @@ static int __init arcfb_init(void)
}
if (ret) {
platform_device_put(arcfb_device);
- driver_unregister(&arcfb_driver);
+ platform_driver_unregister(&arcfb_driver);
}
}
return ret;
@@ -648,7 +648,7 @@ static int __init arcfb_init(void)
static void __exit arcfb_exit(void)
{
platform_device_unregister(arcfb_device);
- driver_unregister(&arcfb_driver);
+ platform_driver_unregister(&arcfb_driver);
}
module_param(num_cols, ulong, 0);
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index bd9a699..6a219b2 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -79,13 +79,13 @@ static void corgibl_blank(int blank)
}
#ifdef CONFIG_PM
-static int corgibl_suspend(struct device *dev, pm_message_t state)
+static int corgibl_suspend(struct platform_device *dev, pm_message_t state)
{
corgibl_blank(FB_BLANK_POWERDOWN);
return 0;
}
-static int corgibl_resume(struct device *dev)
+static int corgibl_resume(struct platform_device *dev)
{
corgibl_blank(FB_BLANK_UNBLANK);
return 0;
@@ -143,9 +143,9 @@ static struct backlight_properties corgibl_data = {
static struct backlight_device *corgi_backlight_device;
-static int __init corgibl_probe(struct device *dev)
+static int __init corgibl_probe(struct platform_device *pdev)
{
- struct corgibl_machinfo *machinfo = dev->platform_data;
+ struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
corgibl_data.max_brightness = machinfo->max_intensity;
corgibl_mach_set_intensity = machinfo->set_bl_intensity;
@@ -162,7 +162,7 @@ static int __init corgibl_probe(struct device *dev)
return 0;
}
-static int corgibl_remove(struct device *dev)
+static int corgibl_remove(struct platform_device *dev)
{
backlight_device_unregister(corgi_backlight_device);
@@ -172,23 +172,24 @@ static int corgibl_remove(struct device *dev)
return 0;
}
-static struct device_driver corgibl_driver = {
- .name = "corgi-bl",
- .bus = &platform_bus_type,
+static struct platform_driver corgibl_driver = {
.probe = corgibl_probe,
.remove = corgibl_remove,
.suspend = corgibl_suspend,
.resume = corgibl_resume,
+ .driver = {
+ .name = "corgi-bl",
+ },
};
static int __init corgibl_init(void)
{
- return driver_register(&corgibl_driver);
+ return platform_driver_register(&corgibl_driver);
}
static void __exit corgibl_exit(void)
{
- driver_unregister(&corgibl_driver);
+ platform_driver_unregister(&corgibl_driver);
}
module_init(corgibl_init);
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index f53bf3ba..d3728f6 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -51,6 +51,9 @@ static struct fb_ops bw2_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = bw2_mmap,
.fb_ioctl = bw2_ioctl,
+#ifdef CONFIG_COMPAT
+ .fb_compat_ioctl = sbusfb_compat_ioctl,
+#endif
};
/* OBio addresses for the bwtwo registers */
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 030d4b1..1bed50f 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -49,6 +49,9 @@ static struct fb_ops cg14_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = cg14_mmap,
.fb_ioctl = cg14_ioctl,
+#ifdef CONFIG_COMPAT
+ .fb_compat_ioctl = sbusfb_compat_ioctl,
+#endif
};
#define CG14_MCR_INTENABLE_SHIFT 7
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index b94eee8..a1354e7 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -50,6 +50,9 @@ static struct fb_ops cg3_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = cg3_mmap,
.fb_ioctl = cg3_ioctl,
+#ifdef CONFIG_COMPAT
+ .fb_compat_ioctl = sbusfb_compat_ioctl,
+#endif
};
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 414c440..9debe64 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -54,6 +54,9 @@ static struct fb_ops cg6_ops = {
.fb_sync = cg6_sync,
.fb_mmap = cg6_mmap,
.fb_ioctl = cg6_ioctl,
+#ifdef CONFIG_COMPAT
+ .fb_compat_ioctl = sbusfb_compat_ioctl,
+#endif
};
/* Offset of interesting structures in the OBIO space */
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 94c5f13..5f74df9 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -215,12 +215,5 @@ config FONT_10x18
big letters. It fits between the sun 12x22 and the normal 8x16 font.
If other fonts are too big or too small for you, say Y, otherwise say N.
-config FONT_RL
- bool "console Roman Large 8x16 font" if FONTS
- depends on FRAMEBUFFER_CONSOLE
- help
- This is the visually-appealing "RL" console font that is
- included with the kbd package.
-
endmenu
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index fed600c..9b26dda 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -15,7 +15,6 @@ font-objs-$(CONFIG_FONT_10x18) += font_10x18.o
font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o
-font-objs-$(CONFIG_FONT_RL) += font_rl.o
font-objs += $(font-objs-y)
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index e7802ff..bcea87c 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -106,8 +106,7 @@ enum {
FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */
};
-struct display fb_display[MAX_NR_CONSOLES];
-EXPORT_SYMBOL(fb_display);
+static struct display fb_display[MAX_NR_CONSOLES];
static signed char con2fb_map[MAX_NR_CONSOLES];
static signed char con2fb_map_boot[MAX_NR_CONSOLES];
@@ -653,13 +652,12 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
{
struct fbcon_ops *ops = info->fbcon_par;
+ ops->p = (p) ? p : &fb_display[vc->vc_num];
+
if ((info->flags & FBINFO_MISC_TILEBLITTING))
fbcon_set_tileops(vc, info, p, ops);
else {
- struct display *disp;
-
- disp = (p) ? p : &fb_display[vc->vc_num];
- fbcon_set_rotation(info, disp);
+ fbcon_set_rotation(info, ops->p);
fbcon_set_bitops(ops);
}
}
@@ -668,11 +666,10 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
struct display *p)
{
struct fbcon_ops *ops = info->fbcon_par;
- struct display *disp;
info->flags &= ~FBINFO_MISC_TILEBLITTING;
- disp = (p) ? p : &fb_display[vc->vc_num];
- fbcon_set_rotation(info, disp);
+ ops->p = (p) ? p : &fb_display[vc->vc_num];
+ fbcon_set_rotation(info, ops->p);
fbcon_set_bitops(ops);
}
#endif /* CONFIG_MISC_TILEBLITTING */
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index accfd7bd..6892e7f 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -52,8 +52,6 @@ struct display {
struct fb_videomode *mode;
};
-extern struct display fb_display[];
-
struct fbcon_ops {
void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width);
@@ -73,6 +71,7 @@ struct fbcon_ops {
struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */
struct timer_list cursor_timer; /* Cursor timer */
struct fb_cursor cursor_state;
+ struct display *p;
int currcon; /* Current VC. */
int cursor_flash;
int cursor_reset;
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
index 680aaba..3afd1ee 100644
--- a/drivers/video/console/fbcon_ccw.c
+++ b/drivers/video/console/fbcon_ccw.c
@@ -63,9 +63,9 @@ static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute,
static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
- struct display *p = &fb_display[vc->vc_num];
+ struct fbcon_ops *ops = info->fbcon_par;
struct fb_copyarea area;
- u32 vyres = GETVYRES(p->scrollmode, info);
+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
area.sx = sy * vc->vc_font.height;
area.sy = vyres - ((sx + width) * vc->vc_font.width);
@@ -80,10 +80,10 @@ static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width)
{
- struct display *p = &fb_display[vc->vc_num];
+ struct fbcon_ops *ops = info->fbcon_par;
struct fb_fillrect region;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
- u32 vyres = GETVYRES(p->scrollmode, info);
+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
region.color = attr_bgcol_ec(bgshift,vc);
region.dx = sy * vc->vc_font.height;
@@ -131,7 +131,6 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
int fg, int bg)
{
struct fb_image image;
- struct display *p = &fb_display[vc->vc_num];
struct fbcon_ops *ops = info->fbcon_par;
u32 width = (vc->vc_font.height + 7)/8;
u32 cellsize = width * vc->vc_font.width;
@@ -141,7 +140,7 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
u32 cnt, pitch, size;
u32 attribute = get_attribute(info, scr_readw(s));
u8 *dst, *buf = NULL;
- u32 vyres = GETVYRES(p->scrollmode, info);
+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
if (!ops->fontbuffer)
return;
@@ -397,9 +396,8 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info,
int ccw_update_start(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
- struct display *p = &fb_display[ops->currcon];
u32 yoffset;
- u32 vyres = GETVYRES(p->scrollmode, info);
+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
int err;
yoffset = (vyres - info->var.yres) - ops->var.xoffset;
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
index 6c6f3b6..6d92b84 100644
--- a/drivers/video/console/fbcon_cw.c
+++ b/drivers/video/console/fbcon_cw.c
@@ -49,9 +49,9 @@ static inline void cw_update_attr(u8 *dst, u8 *src, int attribute,
static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
- struct display *p = &fb_display[vc->vc_num];
+ struct fbcon_ops *ops = info->fbcon_par;
struct fb_copyarea area;
- u32 vxres = GETVXRES(p->scrollmode, info);
+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
area.sx = vxres - ((sy + height) * vc->vc_font.height);
area.sy = sx * vc->vc_font.width;
@@ -66,10 +66,10 @@ static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width)
{
- struct display *p = &fb_display[vc->vc_num];
+ struct fbcon_ops *ops = info->fbcon_par;
struct fb_fillrect region;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
- u32 vxres = GETVXRES(p->scrollmode, info);
+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
region.color = attr_bgcol_ec(bgshift,vc);
region.dx = vxres - ((sy + height) * vc->vc_font.height);
@@ -117,7 +117,6 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info,
int fg, int bg)
{
struct fb_image image;
- struct display *p = &fb_display[vc->vc_num];
struct fbcon_ops *ops = info->fbcon_par;
u32 width = (vc->vc_font.height + 7)/8;
u32 cellsize = width * vc->vc_font.width;
@@ -127,7 +126,7 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info,
u32 cnt, pitch, size;
u32 attribute = get_attribute(info, scr_readw(s));
u8 *dst, *buf = NULL;
- u32 vxres = GETVXRES(p->scrollmode, info);
+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
if (!ops->fontbuffer)
return;
@@ -381,8 +380,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info,
int cw_update_start(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
- struct display *p = &fb_display[ops->currcon];
- u32 vxres = GETVXRES(p->scrollmode, info);
+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
u32 xoffset;
int err;
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
index 2e1d9d4..c4d7c89 100644
--- a/drivers/video/console/fbcon_ud.c
+++ b/drivers/video/console/fbcon_ud.c
@@ -48,10 +48,10 @@ static inline void ud_update_attr(u8 *dst, u8 *src, int attribute,
static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
- struct display *p = &fb_display[vc->vc_num];
+ struct fbcon_ops *ops = info->fbcon_par;
struct fb_copyarea area;
- u32 vyres = GETVYRES(p->scrollmode, info);
- u32 vxres = GETVXRES(p->scrollmode, info);
+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
area.sy = vyres - ((sy + height) * vc->vc_font.height);
area.sx = vxres - ((sx + width) * vc->vc_font.width);
@@ -66,11 +66,11 @@ static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width)
{
- struct display *p = &fb_display[vc->vc_num];
+ struct fbcon_ops *ops = info->fbcon_par;
struct fb_fillrect region;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
- u32 vyres = GETVYRES(p->scrollmode, info);
- u32 vxres = GETVXRES(p->scrollmode, info);
+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
region.color = attr_bgcol_ec(bgshift,vc);
region.dy = vyres - ((sy + height) * vc->vc_font.height);
@@ -153,7 +153,6 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info,
int fg, int bg)
{
struct fb_image image;
- struct display *p = &fb_display[vc->vc_num];
struct fbcon_ops *ops = info->fbcon_par;
u32 width = (vc->vc_font.width + 7)/8;
u32 cellsize = width * vc->vc_font.height;
@@ -163,8 +162,8 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info,
u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
u32 attribute = get_attribute(info, scr_readw(s));
u8 *dst, *buf = NULL;
- u32 vyres = GETVYRES(p->scrollmode, info);
- u32 vxres = GETVXRES(p->scrollmode, info);
+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
if (!ops->fontbuffer)
return;
@@ -421,10 +420,9 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info,
int ud_update_start(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
- struct display *p = &fb_display[ops->currcon];
u32 xoffset, yoffset;
- u32 vyres = GETVYRES(p->scrollmode, info);
- u32 vxres = GETVXRES(p->scrollmode, info);
+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
int err;
xoffset = (vxres - info->var.xres) - ops->var.xoffset;
diff --git a/drivers/video/console/font_rl.c b/drivers/video/console/font_rl.c
deleted file mode 100644
index dfecc27..0000000
--- a/drivers/video/console/font_rl.c
+++ /dev/null
@@ -1,4374 +0,0 @@
-
-/* This font is simply the "rl.fnt" console font from the kbd utility.
- * Converted by Zack T Smith, fbui@comcast.net.
- * The original binary file is covered under the GNU Public License.
- */
-
-#include <linux/font.h>
-
-#define FONTDATAMAX 4096
-
-static unsigned char patterns[4096] = {
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x3c,
-0x42,
-0x81,
-0xe7,
-0xa5,
-0x99,
-0x81,
-0x81,
-0x99,
-0x42,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x3c,
-0x7e,
-0xff,
-0x99,
-0xdb,
-0xe7,
-0xff,
-0xff,
-0xe7,
-0x7e,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x6c,
-0xfe,
-0xfe,
-0xfe,
-0xfe,
-0xfe,
-0x7c,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x7c,
-0xfe,
-0x7c,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x38,
-0x38,
-0x10,
-0xd6,
-0xfe,
-0xd6,
-0x10,
-0x10,
-0x38,
-0x7c,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x38,
-0x7c,
-0xfe,
-0xfe,
-0x54,
-0x10,
-0x10,
-0x38,
-0x7c,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x3c,
-0x3c,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xe7,
-0xc3,
-0xc3,
-0xe7,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x42,
-0x42,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xc3,
-0x99,
-0xbd,
-0xbd,
-0x99,
-0xc3,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-
-0x00,
-0x00,
-0x0f,
-0x07,
-0x0d,
-0x18,
-0x78,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0x78,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x18,
-0x7e,
-0x18,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x08,
-0x0c,
-0x0a,
-0x0a,
-0x0a,
-0x08,
-0x08,
-0x08,
-0x38,
-0x78,
-0x30,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x10,
-0x18,
-0x1c,
-0x1e,
-0x1e,
-0x16,
-0x12,
-0x72,
-0xf2,
-0x62,
-0x0e,
-0x1e,
-0x0c,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x10,
-0x92,
-0x54,
-0x38,
-0xfe,
-0x38,
-0x54,
-0x92,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x80,
-0xc0,
-0xe0,
-0xb8,
-0x8e,
-0xb8,
-0xe0,
-0xc0,
-0x80,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x02,
-0x06,
-0x0e,
-0x3a,
-0xe2,
-0x3a,
-0x0e,
-0x06,
-0x02,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x38,
-0x7c,
-0xd6,
-0x10,
-0x10,
-0x10,
-0x10,
-0xd6,
-0x7c,
-0x38,
-0x10,
-0x00,
-0x00,
-
-0x00,
-0x42,
-0xe7,
-0xe7,
-0xe7,
-0xe7,
-0x42,
-0x42,
-0x42,
-0x00,
-0x66,
-0x66,
-0x66,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x7f,
-0xca,
-0xca,
-0xca,
-0xca,
-0x7a,
-0x0a,
-0x0a,
-0x0a,
-0x0a,
-0x0a,
-0x1b,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1e,
-0x31,
-0x78,
-0xcc,
-0xc6,
-0xc3,
-0x63,
-0x33,
-0x1e,
-0x8c,
-0x78,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0xfe,
-0xfe,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x38,
-0x7c,
-0xd6,
-0x10,
-0x10,
-0x10,
-0x10,
-0xd6,
-0x7c,
-0x38,
-0x10,
-0xfe,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x38,
-0x7c,
-0xd6,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0xd6,
-0x7c,
-0x38,
-0x10,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x08,
-0x0c,
-0x06,
-0xff,
-0x06,
-0x0c,
-0x08,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x30,
-0x60,
-0xff,
-0x60,
-0x30,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x22,
-0x44,
-0x88,
-0xcc,
-0xee,
-0x44,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x24,
-0x42,
-0xff,
-0x42,
-0x24,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x38,
-0x6c,
-0x6c,
-0xc6,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0xfe,
-0xc6,
-0x6c,
-0x6c,
-0x38,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x3c,
-0x3c,
-0x3c,
-0x3c,
-0x18,
-0x18,
-0x18,
-0x10,
-0x00,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x22,
-0x77,
-0x33,
-0x11,
-0x22,
-0x44,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x12,
-0x12,
-0x12,
-0x7f,
-0x24,
-0x24,
-0x24,
-0xfe,
-0x48,
-0x48,
-0x48,
-0x00,
-0x00,
-0x00,
-
-0x10,
-0x10,
-0x7c,
-0xd2,
-0xd0,
-0xd0,
-0xd0,
-0x7c,
-0x16,
-0x16,
-0x16,
-0x96,
-0x7c,
-0x10,
-0x10,
-0x00,
-
-0x00,
-0x42,
-0xbe,
-0x44,
-0x0c,
-0x08,
-0x18,
-0x10,
-0x30,
-0x20,
-0x64,
-0x4a,
-0xc4,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x38,
-0x6c,
-0x6c,
-0x6c,
-0x38,
-0x37,
-0x72,
-0xdc,
-0xcc,
-0xcc,
-0xcc,
-0x77,
-0x00,
-0x00,
-0x00,
-
-0x10,
-0x38,
-0x18,
-0x08,
-0x10,
-0x20,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x04,
-0x08,
-0x10,
-0x10,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x10,
-0x10,
-0x08,
-0x04,
-0x00,
-0x00,
-
-0x00,
-0x20,
-0x10,
-0x08,
-0x08,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x08,
-0x08,
-0x10,
-0x20,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x44,
-0x28,
-0x38,
-0xfe,
-0x38,
-0x28,
-0x44,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x18,
-0x7e,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x18,
-0x08,
-0x10,
-0x20,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x06,
-0x06,
-0x0c,
-0x0c,
-0x18,
-0x18,
-0x30,
-0x30,
-0x60,
-0x60,
-0xc0,
-0xc0,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x46,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc4,
-0x78,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x08,
-0x18,
-0x78,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x7e,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x7c,
-0x86,
-0x06,
-0x0c,
-0x18,
-0x20,
-0x40,
-0xc1,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x46,
-0x04,
-0x08,
-0x1c,
-0x06,
-0x06,
-0x06,
-0x06,
-0x0c,
-0x70,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x04,
-0x08,
-0x10,
-0x2c,
-0x4c,
-0x8c,
-0x8c,
-0xfe,
-0x0c,
-0x0c,
-0x0c,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x02,
-0x3c,
-0x20,
-0x20,
-0x70,
-0x0c,
-0x06,
-0x06,
-0x06,
-0x06,
-0x0c,
-0x70,
-0x00,
-
-0x00,
-0x00,
-0x18,
-0x20,
-0x40,
-0xc0,
-0xdc,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0x44,
-0x38,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x40,
-0x7e,
-0x82,
-0x06,
-0x04,
-0x0c,
-0x18,
-0x18,
-0x30,
-0x30,
-0x30,
-0x30,
-0x00,
-
-0x00,
-0x00,
-0x7c,
-0xc6,
-0xc6,
-0x64,
-0x38,
-0x4c,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0x7c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x38,
-0x44,
-0xc6,
-0xc6,
-0x76,
-0x06,
-0x06,
-0x06,
-0x04,
-0x08,
-0x30,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x18,
-0x08,
-0x10,
-0x20,
-
-0x00,
-0x06,
-0x0c,
-0x18,
-0x30,
-0x60,
-0xa0,
-0xa0,
-0x60,
-0x30,
-0x18,
-0x0c,
-0x06,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x60,
-0x30,
-0x18,
-0x0c,
-0x06,
-0x05,
-0x05,
-0x06,
-0x0c,
-0x18,
-0x30,
-0x60,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x7c,
-0x86,
-0xc6,
-0x06,
-0x04,
-0x08,
-0x10,
-0x10,
-0x18,
-0x00,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x3c,
-0x46,
-0xc6,
-0xce,
-0xd6,
-0xd6,
-0xd6,
-0xdc,
-0xc0,
-0xc4,
-0x78,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x2c,
-0x2c,
-0x2c,
-0x7e,
-0x46,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xfc,
-0x66,
-0x66,
-0x66,
-0x66,
-0x7c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xfc,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3a,
-0x66,
-0xc2,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xfc,
-0x66,
-0x63,
-0x63,
-0x63,
-0x63,
-0x63,
-0x63,
-0x63,
-0x63,
-0x66,
-0xfc,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xff,
-0x61,
-0x60,
-0x60,
-0x64,
-0x7c,
-0x64,
-0x60,
-0x60,
-0x60,
-0x61,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xff,
-0x61,
-0x61,
-0x60,
-0x64,
-0x7c,
-0x64,
-0x60,
-0x60,
-0x60,
-0x60,
-0xf0,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3a,
-0x66,
-0xc2,
-0xc0,
-0xc0,
-0xc0,
-0xcf,
-0xc6,
-0xc6,
-0xc6,
-0x66,
-0x38,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x62,
-0x7e,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1e,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x08,
-0xf0,
-
-0x00,
-0xf7,
-0x64,
-0x6c,
-0x68,
-0x68,
-0x78,
-0x6c,
-0x6c,
-0x6c,
-0x66,
-0x66,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf8,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x61,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xc3,
-0x66,
-0x76,
-0x7e,
-0x56,
-0x56,
-0x46,
-0x46,
-0x46,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xe7,
-0x62,
-0x62,
-0x72,
-0x52,
-0x5a,
-0x4a,
-0x4e,
-0x46,
-0x46,
-0x42,
-0xe2,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x66,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xfc,
-0x66,
-0x66,
-0x66,
-0x66,
-0x6c,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0xf0,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x66,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0x66,
-0x3c,
-0x10,
-0x39,
-0x0e,
-
-0x00,
-0xfc,
-0x66,
-0x66,
-0x66,
-0x66,
-0x7c,
-0x6c,
-0x66,
-0x66,
-0x66,
-0x66,
-0xf3,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x7a,
-0xc6,
-0xc2,
-0xc0,
-0x70,
-0x3c,
-0x0e,
-0x06,
-0x06,
-0x86,
-0xc6,
-0xbc,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xff,
-0x99,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x76,
-0x34,
-0x34,
-0x34,
-0x3c,
-0x18,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x62,
-0x6a,
-0x6a,
-0x6a,
-0x6a,
-0x7e,
-0x7e,
-0x34,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x34,
-0x34,
-0x18,
-0x18,
-0x2c,
-0x2c,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x34,
-0x34,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x7f,
-0x46,
-0x86,
-0x0c,
-0x0c,
-0x18,
-0x18,
-0x30,
-0x30,
-0x61,
-0x62,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xc0,
-0xc0,
-0x60,
-0x60,
-0x30,
-0x30,
-0x18,
-0x18,
-0x0c,
-0x0c,
-0x06,
-0x06,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x10,
-0x38,
-0x4c,
-0x86,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x20,
-0x30,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x20,
-0xe0,
-0x60,
-0x60,
-0x6c,
-0x76,
-0x66,
-0x66,
-0x66,
-0x66,
-0x76,
-0x6c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x60,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x04,
-0x1c,
-0x0c,
-0x0c,
-0x6c,
-0xdc,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0xdc,
-0x66,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x7e,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1e,
-0x31,
-0x33,
-0x30,
-0x30,
-0x78,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x78,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7b,
-0xce,
-0xcc,
-0xcc,
-0xcc,
-0x78,
-0x60,
-0x7c,
-0x86,
-0xc6,
-0x7c,
-
-0x00,
-0x20,
-0xe0,
-0x60,
-0x60,
-0x6c,
-0x76,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x10,
-0x38,
-0x10,
-0x00,
-0x18,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x08,
-0x1c,
-0x08,
-0x00,
-0x0c,
-0x1c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x6c,
-0x4c,
-0x38,
-0x00,
-
-0x00,
-0x20,
-0xe0,
-0x60,
-0x60,
-0x67,
-0x66,
-0x6c,
-0x78,
-0x6c,
-0x6c,
-0x66,
-0xe7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x08,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x6a,
-0xfe,
-0x6a,
-0x6a,
-0x6a,
-0x62,
-0x62,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x5c,
-0xf6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x5c,
-0xe6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x7c,
-0x60,
-0x60,
-0xf0,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x76,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0x7c,
-0x0c,
-0x0c,
-0x1e,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x5e,
-0xf6,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0xf0,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7a,
-0xc6,
-0x72,
-0x1c,
-0x06,
-0x86,
-0xc6,
-0xbc,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x10,
-0x30,
-0x7c,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x34,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xee,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x3a,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf7,
-0x62,
-0x76,
-0x34,
-0x34,
-0x3c,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf7,
-0x62,
-0x6a,
-0x6a,
-0x6a,
-0x6a,
-0x7e,
-0x24,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf7,
-0x62,
-0x34,
-0x18,
-0x2c,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf7,
-0x62,
-0x62,
-0x34,
-0x34,
-0x18,
-0x18,
-0x18,
-0x10,
-0xb0,
-0xe0,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0x8c,
-0x18,
-0x30,
-0x30,
-0x60,
-0xc2,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x0e,
-0x18,
-0x10,
-0x10,
-0x08,
-0x70,
-0x70,
-0x08,
-0x10,
-0x10,
-0x18,
-0x0e,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x00,
-0x00,
-
-0x00,
-0x70,
-0x18,
-0x08,
-0x08,
-0x10,
-0x0e,
-0x0e,
-0x10,
-0x08,
-0x08,
-0x18,
-0x70,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x76,
-0xdc,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x6c,
-0xc6,
-0xc6,
-0xc6,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x3a,
-0x66,
-0xc2,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0x62,
-0x3c,
-0x18,
-0x0c,
-0x24,
-0x18,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0xee,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3b,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x0c,
-0x18,
-0x20,
-0x00,
-0x3c,
-0x66,
-0x7e,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x58,
-0x8c,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x18,
-0x04,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x38,
-0x44,
-0x44,
-0x38,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x60,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x08,
-0x24,
-0x18,
-
-0x00,
-0x18,
-0x2c,
-0x46,
-0x00,
-0x3c,
-0x66,
-0x7e,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x7e,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x18,
-0x04,
-0x00,
-0x3c,
-0x66,
-0x7e,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x2c,
-0x46,
-0x00,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x60,
-0x30,
-0x08,
-0x00,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x66,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x2c,
-0x2c,
-0x2c,
-0x7e,
-0x46,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x24,
-0x18,
-0x18,
-0x3c,
-0x2c,
-0x2c,
-0x2c,
-0x7e,
-0x46,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x0c,
-0x18,
-0xff,
-0x61,
-0x60,
-0x60,
-0x64,
-0x7c,
-0x64,
-0x60,
-0x60,
-0x61,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x76,
-0x9b,
-0x1b,
-0x3f,
-0xd8,
-0xd8,
-0xd9,
-0x6e,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1f,
-0x1d,
-0x1d,
-0x3c,
-0x2c,
-0x2e,
-0x2c,
-0x7c,
-0x4c,
-0x4c,
-0x4d,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x2c,
-0x46,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x18,
-0x04,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x2c,
-0x46,
-0x00,
-0xee,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x3a,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x18,
-0x04,
-0x00,
-0xee,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x3a,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0xf7,
-0x62,
-0x62,
-0x34,
-0x34,
-0x18,
-0x18,
-0x18,
-0x10,
-0xb0,
-0xe0,
-
-0x66,
-0x00,
-0x3c,
-0x66,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x66,
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x10,
-0x10,
-0x7c,
-0xc6,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0xc2,
-0x7c,
-0x10,
-0x10,
-0x00,
-
-0x00,
-0x38,
-0x64,
-0x6c,
-0x60,
-0x60,
-0xf0,
-0x60,
-0x60,
-0x60,
-0x60,
-0x66,
-0xfc,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x81,
-0xc3,
-0x66,
-0x3c,
-0x18,
-0xff,
-0x18,
-0x18,
-0xff,
-0x18,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xfe,
-0x63,
-0x63,
-0x63,
-0x63,
-0x6e,
-0x60,
-0x64,
-0x6e,
-0x64,
-0x64,
-0xf5,
-0x06,
-0x00,
-0x00,
-
-0x00,
-0x0e,
-0x19,
-0x1b,
-0x18,
-0x18,
-0x3c,
-0x18,
-0x18,
-0x18,
-0x18,
-0xd8,
-0x98,
-0x70,
-0x00,
-0x00,
-
-0x00,
-0x0c,
-0x18,
-0x20,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x06,
-0x0c,
-0x10,
-0x00,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x0c,
-0x18,
-0x20,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x0c,
-0x18,
-0x20,
-0x00,
-0xee,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x3a,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x32,
-0x4c,
-0x00,
-0x5c,
-0xf6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x32,
-0x4c,
-0x00,
-0xe7,
-0x72,
-0x52,
-0x5a,
-0x4a,
-0x4e,
-0x46,
-0x46,
-0x42,
-0xe2,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x30,
-0x00,
-0x30,
-0x10,
-0x10,
-0x20,
-0x40,
-0xc0,
-0xc6,
-0xc2,
-0x7c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0x06,
-0x06,
-0x06,
-0x06,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x20,
-0xe0,
-0x63,
-0x66,
-0xfc,
-0x18,
-0x30,
-0x60,
-0xce,
-0x93,
-0x06,
-0x0c,
-0x1f,
-0x00,
-0x00,
-
-0x00,
-0x20,
-0xe0,
-0x63,
-0x66,
-0xfc,
-0x18,
-0x30,
-0x64,
-0xc8,
-0x96,
-0x3f,
-0x06,
-0x06,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x18,
-0x00,
-0x08,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x3c,
-0x3c,
-0x3c,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x36,
-0x6c,
-0xd8,
-0xd8,
-0x6c,
-0x36,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xd8,
-0x6c,
-0x36,
-0x36,
-0x6c,
-0xd8,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-
-0x00,
-0x95,
-0x00,
-0xa9,
-0x00,
-0x95,
-0x00,
-0xa9,
-0x00,
-0x95,
-0x00,
-0xa9,
-0x00,
-0x95,
-0x00,
-0xa9,
-
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xf8,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xf8,
-0x18,
-0x18,
-0xf8,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xe6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf8,
-0x18,
-0x18,
-0xf8,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xe6,
-0x06,
-0x06,
-0xe6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0x06,
-0x06,
-0xe6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xe6,
-0x06,
-0x06,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xf8,
-0x18,
-0x18,
-0xf8,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf8,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x1f,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x1f,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xff,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x1f,
-0x18,
-0x18,
-0x1f,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x60,
-0x60,
-0x7f,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7f,
-0x60,
-0x60,
-0x67,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xe7,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0xe7,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x60,
-0x60,
-0x67,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xe7,
-0x00,
-0x00,
-0xe7,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xff,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0xff,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x7f,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x1f,
-0x18,
-0x18,
-0x1f,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x1f,
-0x18,
-0x18,
-0x1f,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7f,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xff,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xff,
-0x00,
-0x00,
-0xff,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xf8,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x1f,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x77,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0xde,
-0x73,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x7c,
-0xc6,
-0xc6,
-0xc6,
-0xc4,
-0xc8,
-0xc4,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xdc,
-0xc0,
-0xc0,
-0x00,
-
-0x00,
-0xff,
-0x61,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0xf0,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x01,
-0x7e,
-0xa4,
-0x24,
-0x2c,
-0x6c,
-0x6c,
-0x6c,
-0x48,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xff,
-0xc1,
-0x60,
-0x30,
-0x18,
-0x0c,
-0x18,
-0x30,
-0x60,
-0xc0,
-0xc1,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7f,
-0xc8,
-0xc8,
-0xc8,
-0xc8,
-0xc8,
-0xc8,
-0x70,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x22,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x7c,
-0x60,
-0x60,
-0x60,
-0xc0,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x76,
-0xdc,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x10,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x38,
-0x10,
-0x7c,
-0xd6,
-0xd6,
-0xd6,
-0xd6,
-0xd6,
-0xd6,
-0x7c,
-0x10,
-0x38,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x38,
-0x6c,
-0xc6,
-0xc6,
-0xc6,
-0xfe,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0x6c,
-0x38,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x66,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0x66,
-0x24,
-0x24,
-0xa5,
-0xe7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1e,
-0x31,
-0x30,
-0x18,
-0x0c,
-0x3e,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x6e,
-0xff,
-0x99,
-0x99,
-0x99,
-0x99,
-0xff,
-0x76,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x02,
-0x04,
-0x7c,
-0xca,
-0x92,
-0xa6,
-0x7c,
-0x40,
-0x80,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1c,
-0x30,
-0x60,
-0x60,
-0x60,
-0x7c,
-0x60,
-0x60,
-0x60,
-0x60,
-0x30,
-0x1c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x7c,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x7c,
-0x00,
-0x00,
-0x00,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x18,
-0x7e,
-0x18,
-0x18,
-0x00,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x30,
-0x18,
-0x0c,
-0x06,
-0x0c,
-0x18,
-0x30,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x0c,
-0x18,
-0x30,
-0x60,
-0x30,
-0x18,
-0x0c,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x0e,
-0x19,
-0x1b,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xd8,
-0x98,
-0x70,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x18,
-0x00,
-0x7e,
-0x00,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x76,
-0xdc,
-0x00,
-0x00,
-0x76,
-0xdc,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x38,
-0x44,
-0x44,
-0x44,
-0x38,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x07,
-0x06,
-0x06,
-0x0c,
-0x0c,
-0x08,
-0x98,
-0xd0,
-0xf0,
-0x60,
-0x20,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xcc,
-0x76,
-0x66,
-0x66,
-0x66,
-0x66,
-0xf7,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x70,
-0x98,
-0x18,
-0x30,
-0x60,
-0x88,
-0xf8,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7c,
-0x64,
-0x64,
-0x64,
-0x64,
-0x64,
-0x7c,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-};
-
-
-const struct font_desc font_rl = {
- RL_IDX,
- "RomanLarge",
- 8,
- 16,
- patterns,
- -1
-};
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index 9be83be..4fd07d9 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -64,10 +64,6 @@ static const struct font_desc *fonts[] = {
#undef NO_FONTS
&font_mini_4x6,
#endif
-#ifdef CONFIG_FONT_RL
-#undef NO_FONTS
- &font_rl,
-#endif
};
#define num_fonts (sizeof(fonts)/sizeof(*fonts))
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index 957a3ad..5abd3cb 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -227,9 +227,8 @@ void dnfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
* Initialization
*/
-static int __devinit dnfb_probe(struct device *device)
+static int __devinit dnfb_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(device);
struct fb_info *info;
int err = 0;
@@ -257,7 +256,7 @@ static int __devinit dnfb_probe(struct device *device)
framebuffer_release(info);
return err;
}
- dev_set_drvdata(&dev->dev, info);
+ platform_set_drvdata(dev, info);
/* now we have registered we can safely setup the hardware */
out_8(AP_CONTROL_3A, RESET_CREG);
@@ -271,10 +270,11 @@ static int __devinit dnfb_probe(struct device *device)
return err;
}
-static struct device_driver dnfb_driver = {
- .name = "dnfb",
- .bus = &platform_bus_type,
+static struct platform_driver dnfb_driver = {
.probe = dnfb_probe,
+ .driver = {
+ .name = "dnfb",
+ },
};
static struct platform_device dnfb_device = {
@@ -288,12 +288,12 @@ int __init dnfb_init(void)
if (fb_get_options("dnfb", NULL))
return -ENODEV;
- ret = driver_register(&dnfb_driver);
+ ret = platform_driver_register(&dnfb_driver);
if (!ret) {
ret = platform_device_register(&dnfb_device);
if (ret)
- driver_unregister(&dnfb_driver);
+ platform_driver_unregister(&dnfb_driver);
}
return ret;
}
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 6a81a1d..3b0e713 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -609,9 +609,9 @@ static void epson1355fb_platform_release(struct device *device)
{
}
-static int epson1355fb_remove(struct device *device)
+static int epson1355fb_remove(struct platform_device *dev)
{
- struct fb_info *info = dev_get_drvdata(device);
+ struct fb_info *info = platform_get_drvdata(dev);
struct epson1355_par *par = info->par;
backlight_enable(0);
@@ -632,9 +632,8 @@ static int epson1355fb_remove(struct device *device)
return 0;
}
-int __init epson1355fb_probe(struct device *device)
+int __init epson1355fb_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(device);
struct epson1355_par *default_par;
struct fb_info *info;
u8 revision;
@@ -713,7 +712,7 @@ int __init epson1355fb_probe(struct device *device)
/*
* Our driver data.
*/
- dev_set_drvdata(&dev->dev, info);
+ platform_set_drvdata(dev, info);
printk(KERN_INFO "fb%d: %s frame buffer device\n",
info->node, info->fix.id);
@@ -721,15 +720,16 @@ int __init epson1355fb_probe(struct device *device)
return 0;
bail:
- epson1355fb_remove(device);
+ epson1355fb_remove(dev);
return rc;
}
-static struct device_driver epson1355fb_driver = {
- .name = "epson1355fb",
- .bus = &platform_bus_type,
+static struct platform_driver epson1355fb_driver = {
.probe = epson1355fb_probe,
.remove = epson1355fb_remove,
+ .driver = {
+ .name = "epson1355fb",
+ },
};
static struct platform_device epson1355fb_device = {
@@ -747,11 +747,11 @@ int __init epson1355fb_init(void)
if (fb_get_options("epson1355fb", NULL))
return -ENODEV;
- ret = driver_register(&epson1355fb_driver);
+ ret = platform_driver_register(&epson1355fb_driver);
if (!ret) {
ret = platform_device_register(&epson1355fb_device);
if (ret)
- driver_unregister(&epson1355fb_driver);
+ platform_driver_unregister(&epson1355fb_driver);
}
return ret;
}
@@ -762,7 +762,7 @@ module_init(epson1355fb_init);
static void __exit epson1355fb_exit(void)
{
platform_device_unregister(&epson1355fb_device);
- driver_unregister(&epson1355fb_driver);
+ platform_driver_unregister(&epson1355fb_driver);
}
/* ------------------------------------------------------------------------- */
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 04417dc..2584dae 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -57,6 +57,9 @@ static struct fb_ops ffb_ops = {
.fb_sync = ffb_sync,
.fb_mmap = ffb_mmap,
.fb_ioctl = ffb_ioctl,
+#ifdef CONFIG_COMPAT
+ .fb_compat_ioctl = sbusfb_compat_ioctl,
+#endif
};
/* Register layout and definitions */
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 9d5e4f3..d744c51 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -1105,12 +1105,11 @@ int __init gbefb_setup(char *options)
return 0;
}
-static int __init gbefb_probe(struct device *dev)
+static int __init gbefb_probe(struct platform_device *p_dev)
{
int i, ret = 0;
struct fb_info *info;
struct gbefb_par *par;
- struct platform_device *p_dev = to_platform_device(dev);
#ifndef MODULE
char *options = NULL;
#endif
@@ -1204,8 +1203,8 @@ static int __init gbefb_probe(struct device *dev)
goto out_gbe_unmap;
}
- dev_set_drvdata(&p_dev->dev, info);
- gbefb_create_sysfs(dev);
+ platform_set_drvdata(p_dev, info);
+ gbefb_create_sysfs(&p_dev->dev);
printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
@@ -1231,10 +1230,9 @@ out_release_framebuffer:
return ret;
}
-static int __devexit gbefb_remove(struct device* dev)
+static int __devexit gbefb_remove(struct platform_device* p_dev)
{
- struct platform_device *p_dev = to_platform_device(dev);
- struct fb_info *info = dev_get_drvdata(&p_dev->dev);
+ struct fb_info *info = platform_get_drvdata(p_dev);
unregister_framebuffer(info);
gbe_turn_off();
@@ -1252,18 +1250,19 @@ static int __devexit gbefb_remove(struct device* dev)
return 0;
}
-static struct device_driver gbefb_driver = {
- .name = "gbefb",
- .bus = &platform_bus_type,
+static struct platform_driver gbefb_driver = {
.probe = gbefb_probe,
.remove = __devexit_p(gbefb_remove),
+ .driver = {
+ .name = "gbefb",
+ },
};
static struct platform_device *gbefb_device;
int __init gbefb_init(void)
{
- int ret = driver_register(&gbefb_driver);
+ int ret = platform_driver_register(&gbefb_driver);
if (!ret) {
gbefb_device = platform_device_alloc("gbefb", 0);
if (gbefb_device) {
@@ -1273,7 +1272,7 @@ int __init gbefb_init(void)
}
if (ret) {
platform_device_put(gbefb_device);
- driver_unregister(&gbefb_driver);
+ platform_driver_unregister(&gbefb_driver);
}
}
return ret;
@@ -1282,7 +1281,7 @@ int __init gbefb_init(void)
void __exit gbefb_exit(void)
{
platform_device_unregister(gbefb_device);
- driver_unregister(&gbefb_driver);
+ platform_driver_unregister(&gbefb_driver);
}
module_init(gbefb_init);
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index e20b9f3..5924cc2 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -423,18 +423,18 @@ static void imxfb_setup_gpio(struct imxfb_info *fbi)
* Power management hooks. Note that we won't be called from IRQ context,
* unlike the blank functions above, so we may sleep.
*/
-static int imxfb_suspend(struct device *dev, pm_message_t state)
+static int imxfb_suspend(struct platform_device *dev, pm_message_t state)
{
- struct imxfb_info *fbi = dev_get_drvdata(dev);
+ struct imxfb_info *fbi = platform_get_drvdata(dev);
pr_debug("%s\n",__FUNCTION__);
imxfb_disable_controller(fbi);
return 0;
}
-static int imxfb_resume(struct device *dev)
+static int imxfb_resume(struct platform_device *dev)
{
- struct imxfb_info *fbi = dev_get_drvdata(dev);
+ struct imxfb_info *fbi = platform_get_drvdata(dev);
pr_debug("%s\n",__FUNCTION__);
imxfb_enable_controller(fbi);
@@ -538,9 +538,8 @@ static int __init imxfb_map_video_memory(struct fb_info *info)
return fbi->map_cpu ? 0 : -ENOMEM;
}
-static int __init imxfb_probe(struct device *dev)
+static int __init imxfb_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct imxfb_info *fbi;
struct fb_info *info;
struct imxfb_mach_info *inf;
@@ -553,21 +552,21 @@ static int __init imxfb_probe(struct device *dev)
if(!res)
return -ENODEV;
- inf = dev->platform_data;
+ inf = pdev->dev.platform_data;
if(!inf) {
dev_err(dev,"No platform_data available\n");
return -ENOMEM;
}
- info = framebuffer_alloc(sizeof(struct imxfb_info), dev);
+ info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
if(!info)
return -ENOMEM;
fbi = info->par;
- dev_set_drvdata(dev, info);
+ platform_set_drvdata(pdev, info);
- ret = imxfb_init_fbinfo(dev);
+ ret = imxfb_init_fbinfo(&pdev->dev);
if( ret < 0 )
goto failed_init;
@@ -621,22 +620,21 @@ failed_register:
fb_dealloc_cmap(&info->cmap);
failed_cmap:
if (!inf->fixed_screen_cpu)
- dma_free_writecombine(dev,fbi->map_size,fbi->map_cpu,
+ dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
fbi->map_dma);
failed_map:
kfree(info->pseudo_palette);
failed_regs:
release_mem_region(res->start, res->end - res->start);
failed_init:
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
framebuffer_release(info);
return ret;
}
-static int imxfb_remove(struct device *dev)
+static int imxfb_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct fb_info *info = dev_get_drvdata(dev);
+ struct fb_info *info = platform_get_drvdata(pdev);
struct imxfb_info *fbi = info->par;
struct resource *res;
@@ -651,36 +649,37 @@ static int imxfb_remove(struct device *dev)
framebuffer_release(info);
release_mem_region(res->start, res->end - res->start + 1);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
return 0;
}
-void imxfb_shutdown(struct device * dev)
+void imxfb_shutdown(struct platform_device * dev)
{
- struct fb_info *info = dev_get_drvdata(dev);
+ struct fb_info *info = platform_get_drvdata(dev);
struct imxfb_info *fbi = info->par;
imxfb_disable_controller(fbi);
}
-static struct device_driver imxfb_driver = {
- .name = "imx-fb",
- .bus = &platform_bus_type,
+static struct platform_driver imxfb_driver = {
.probe = imxfb_probe,
.suspend = imxfb_suspend,
.resume = imxfb_resume,
.remove = imxfb_remove,
.shutdown = imxfb_shutdown,
+ .driver = {
+ .name = "imx-fb",
+ },
};
int __init imxfb_init(void)
{
- return driver_register(&imxfb_driver);
+ return platform_driver_register(&imxfb_driver);
}
static void __exit imxfb_cleanup(void)
{
- driver_unregister(&imxfb_driver);
+ platform_driver_unregister(&imxfb_driver);
}
module_init(imxfb_init);
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 84a7fe4..376d4a1 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -51,6 +51,9 @@ static struct fb_ops leo_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = leo_mmap,
.fb_ioctl = leo_ioctl,
+#ifdef CONFIG_COMPAT
+ .fb_compat_ioctl = sbusfb_compat_ioctl,
+#endif
};
#define LEO_OFF_LC_SS0_KRN 0x00200000UL
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index f60b1f4..3353103 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -42,7 +42,7 @@ int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
#define nvidia_probe_i2c_connector(p, c, edid) (-1)
#endif
-#ifdef CONFIG_FB_OF
+#ifdef CONFIG_PPC_OF
int nvidia_probe_of_connector(struct fb_info *info, int conn,
u8 ** out_edid);
#else
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 0b40a2a..bee09c6 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -1301,7 +1301,7 @@ static int nvidiafb_pan_display(struct fb_var_screeninfo *var,
struct nvidia_par *par = info->par;
u32 total;
- total = info->var.yoffset * info->fix.line_length + info->var.xoffset;
+ total = var->yoffset * info->fix.line_length + var->xoffset;
NVSetStartAddress(par, total);
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 2c85683..00d87f5 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -26,6 +26,7 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
+#include <linux/pci.h>
#include <asm/io.h>
#include <asm/prom.h>
@@ -325,8 +326,8 @@ static void __init offb_init_nodriver(struct device_node *dp)
int *pp, i;
unsigned int len;
int width = 640, height = 480, depth = 8, pitch;
- unsigned *up;
- unsigned long address;
+ unsigned int rsize, *up;
+ unsigned long address = 0;
if ((pp = (int *) get_property(dp, "depth", &len)) != NULL
&& len == sizeof(int))
@@ -344,10 +345,40 @@ static void __init offb_init_nodriver(struct device_node *dp)
pitch = 0x1000;
} else
pitch = width;
- if ((up = (unsigned *) get_property(dp, "address", &len)) != NULL
- && len == sizeof(unsigned))
+
+ rsize = (unsigned long)pitch * (unsigned long)height *
+ (unsigned long)(depth / 8);
+
+ /* Try to match device to a PCI device in order to get a properly
+ * translated address rather then trying to decode the open firmware
+ * stuff in various incorrect ways
+ */
+#ifdef CONFIG_PCI
+ /* First try to locate the PCI device if any */
+ {
+ struct pci_dev *pdev = NULL;
+
+ for_each_pci_dev(pdev) {
+ if (dp == pci_device_to_OF_node(pdev))
+ break;
+ }
+ if (pdev) {
+ for (i = 0; i < 6 && address == 0; i++) {
+ if ((pci_resource_flags(pdev, i) &
+ IORESOURCE_MEM) &&
+ (pci_resource_len(pdev, i) >= rsize))
+ address = pci_resource_start(pdev, i);
+ }
+ pci_dev_put(pdev);
+ }
+ }
+#endif /* CONFIG_PCI */
+
+ if (address == 0 &&
+ (up = (unsigned *) get_property(dp, "address", &len)) != NULL &&
+ len == sizeof(unsigned))
address = (u_long) * up;
- else {
+ if (address == 0) {
for (i = 0; i < dp->n_addrs; ++i)
if (dp->addrs[i].size >=
pitch * height * depth / 8)
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 9aaf65f..18bcda2 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -48,6 +48,9 @@ static struct fb_ops p9100_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = p9100_mmap,
.fb_ioctl = p9100_ioctl,
+#ifdef CONFIG_COMPAT
+ .fb_compat_ioctl = sbusfb_compat_ioctl,
+#endif
};
/* P9100 control registers */
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index f305a5b..7b4cd25 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -980,17 +980,17 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data)
* Power management hooks. Note that we won't be called from IRQ context,
* unlike the blank functions above, so we may sleep.
*/
-static int pxafb_suspend(struct device *dev, pm_message_t state)
+static int pxafb_suspend(struct platform_device *dev, pm_message_t state)
{
- struct pxafb_info *fbi = dev_get_drvdata(dev);
+ struct pxafb_info *fbi = platform_get_drvdata(dev);
set_ctrlr_state(fbi, C_DISABLE_PM);
return 0;
}
-static int pxafb_resume(struct device *dev)
+static int pxafb_resume(struct platform_device *dev)
{
- struct pxafb_info *fbi = dev_get_drvdata(dev);
+ struct pxafb_info *fbi = platform_get_drvdata(dev);
set_ctrlr_state(fbi, C_ENABLE_PM);
return 0;
@@ -1268,7 +1268,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
}
#endif
-int __init pxafb_probe(struct device *dev)
+int __init pxafb_probe(struct platform_device *dev)
{
struct pxafb_info *fbi;
struct pxafb_mach_info *inf;
@@ -1276,14 +1276,14 @@ int __init pxafb_probe(struct device *dev)
dev_dbg(dev, "pxafb_probe\n");
- inf = dev->platform_data;
+ inf = dev->dev.platform_data;
ret = -ENOMEM;
fbi = NULL;
if (!inf)
goto failed;
#ifdef CONFIG_FB_PXA_PARAMETERS
- ret = pxafb_parse_options(dev, g_options);
+ ret = pxafb_parse_options(&dev->dev, g_options);
if (ret < 0)
goto failed;
#endif
@@ -1293,36 +1293,36 @@ int __init pxafb_probe(struct device *dev)
* a warning is given. */
if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK)
- dev_warn(dev, "machine LCCR0 setting contains illegal bits: %08x\n",
+ dev_warn(&dev->dev, "machine LCCR0 setting contains illegal bits: %08x\n",
inf->lccr0 & LCCR0_INVALID_CONFIG_MASK);
if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
- dev_warn(dev, "machine LCCR3 setting contains illegal bits: %08x\n",
+ dev_warn(&dev->dev, "machine LCCR3 setting contains illegal bits: %08x\n",
inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
if (inf->lccr0 & LCCR0_DPD &&
((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas ||
(inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl ||
(inf->lccr0 & LCCR0_CMS) != LCCR0_Mono))
- dev_warn(dev, "Double Pixel Data (DPD) mode is only valid in passive mono"
+ dev_warn(&dev->dev, "Double Pixel Data (DPD) mode is only valid in passive mono"
" single panel mode\n");
if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
(inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
- dev_warn(dev, "Dual panel only valid in passive mode\n");
+ dev_warn(&dev->dev, "Dual panel only valid in passive mode\n");
if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
(inf->upper_margin || inf->lower_margin))
- dev_warn(dev, "Upper and lower margins must be 0 in passive mode\n");
+ dev_warn(&dev->dev, "Upper and lower margins must be 0 in passive mode\n");
#endif
- dev_dbg(dev, "got a %dx%dx%d LCD\n",inf->xres, inf->yres, inf->bpp);
+ dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",inf->xres, inf->yres, inf->bpp);
if (inf->xres == 0 || inf->yres == 0 || inf->bpp == 0) {
- dev_err(dev, "Invalid resolution or bit depth\n");
+ dev_err(&dev->dev, "Invalid resolution or bit depth\n");
ret = -EINVAL;
goto failed;
}
pxafb_backlight_power = inf->pxafb_backlight_power;
pxafb_lcd_power = inf->pxafb_lcd_power;
- fbi = pxafb_init_fbinfo(dev);
+ fbi = pxafb_init_fbinfo(&dev->dev);
if (!fbi) {
- dev_err(dev, "Failed to initialize framebuffer device\n");
+ dev_err(&dev->dev, "Failed to initialize framebuffer device\n");
ret = -ENOMEM; // only reason for pxafb_init_fbinfo to fail is kmalloc
goto failed;
}
@@ -1330,14 +1330,14 @@ int __init pxafb_probe(struct device *dev)
/* Initialize video memory */
ret = pxafb_map_video_memory(fbi);
if (ret) {
- dev_err(dev, "Failed to allocate video RAM: %d\n", ret);
+ dev_err(&dev->dev, "Failed to allocate video RAM: %d\n", ret);
ret = -ENOMEM;
goto failed;
}
ret = request_irq(IRQ_LCD, pxafb_handle_irq, SA_INTERRUPT, "LCD", fbi);
if (ret) {
- dev_err(dev, "request_irq failed: %d\n", ret);
+ dev_err(&dev->dev, "request_irq failed: %d\n", ret);
ret = -EBUSY;
goto failed;
}
@@ -1349,11 +1349,11 @@ int __init pxafb_probe(struct device *dev)
pxafb_check_var(&fbi->fb.var, &fbi->fb);
pxafb_set_par(&fbi->fb);
- dev_set_drvdata(dev, fbi);
+ platform_set_drvdata(dev, fbi);
ret = register_framebuffer(&fbi->fb);
if (ret < 0) {
- dev_err(dev, "Failed to register framebuffer device: %d\n", ret);
+ dev_err(&dev->dev, "Failed to register framebuffer device: %d\n", ret);
goto failed;
}
@@ -1376,19 +1376,20 @@ int __init pxafb_probe(struct device *dev)
return 0;
failed:
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
kfree(fbi);
return ret;
}
-static struct device_driver pxafb_driver = {
- .name = "pxa2xx-fb",
- .bus = &platform_bus_type,
+static struct platform_driver pxafb_driver = {
.probe = pxafb_probe,
#ifdef CONFIG_PM
.suspend = pxafb_suspend,
.resume = pxafb_resume,
#endif
+ .driver = {
+ .name = "pxa2xx-fb",
+ },
};
#ifndef MODULE
@@ -1415,7 +1416,7 @@ int __devinit pxafb_init(void)
return -ENODEV;
pxafb_setup(option);
#endif
- return driver_register(&pxafb_driver);
+ return platform_driver_register(&pxafb_driver);
}
module_init(pxafb_init);
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index bfc41f2..fc91dbf 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -86,9 +86,8 @@ static struct fb_ops q40fb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int __init q40fb_probe(struct device *device)
+static int __init q40fb_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(device);
struct fb_info *info;
if (!MACH_IS_Q40)
@@ -128,10 +127,11 @@ static int __init q40fb_probe(struct device *device)
return 0;
}
-static struct device_driver q40fb_driver = {
- .name = "q40fb",
- .bus = &platform_bus_type,
+static struct platform_driver q40fb_driver = {
.probe = q40fb_probe,
+ .driver = {
+ .name = "q40fb",
+ },
};
static struct platform_device q40fb_device = {
@@ -145,12 +145,12 @@ int __init q40fb_init(void)
if (fb_get_options("q40fb", NULL))
return -ENODEV;
- ret = driver_register(&q40fb_driver);
+ ret = platform_driver_register(&q40fb_driver);
if (!ret) {
ret = platform_device_register(&q40fb_device);
if (ret)
- driver_unregister(&q40fb_driver);
+ platform_driver_unregister(&q40fb_driver);
}
return ret;
}
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index 3edbd14..e5d0f92 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -503,10 +503,9 @@ s1d13xxxfb_fetch_hw_state(struct fb_info *info)
static int
-s1d13xxxfb_remove(struct device *dev)
+s1d13xxxfb_remove(struct platform_device *pdev)
{
- struct fb_info *info = dev_get_drvdata(dev);
- struct platform_device *pdev = to_platform_device(dev);
+ struct fb_info *info = platform_get_drvdata(pdev);
struct s1d13xxxfb_par *par = NULL;
if (info) {
@@ -534,9 +533,8 @@ s1d13xxxfb_remove(struct device *dev)
}
static int __devinit
-s1d13xxxfb_probe(struct device *dev)
+s1d13xxxfb_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct s1d13xxxfb_par *default_par;
struct fb_info *info;
struct s1d13xxxfb_pdata *pdata = NULL;
@@ -548,8 +546,8 @@ s1d13xxxfb_probe(struct device *dev)
printk(KERN_INFO "Epson S1D13XXX FB Driver\n");
/* enable platform-dependent hardware glue, if any */
- if (dev->platform_data)
- pdata = dev->platform_data;
+ if (pdev->dev.platform_data)
+ pdata = pdev->dev.platform_data;
if (pdata && pdata->platform_init_video)
pdata->platform_init_video();
@@ -572,14 +570,14 @@ s1d13xxxfb_probe(struct device *dev)
if (!request_mem_region(pdev->resource[0].start,
pdev->resource[0].end - pdev->resource[0].start +1, "s1d13xxxfb mem")) {
- dev_dbg(dev, "request_mem_region failed\n");
+ dev_dbg(&pdev->dev, "request_mem_region failed\n");
ret = -EBUSY;
goto bail;
}
if (!request_mem_region(pdev->resource[1].start,
pdev->resource[1].end - pdev->resource[1].start +1, "s1d13xxxfb regs")) {
- dev_dbg(dev, "request_mem_region failed\n");
+ dev_dbg(&pdev->dev, "request_mem_region failed\n");
ret = -EBUSY;
goto bail;
}
@@ -640,7 +638,7 @@ s1d13xxxfb_probe(struct device *dev)
goto bail;
}
- dev_set_drvdata(&pdev->dev, info);
+ platform_set_drvdata(pdev, info);
printk(KERN_INFO "fb%d: %s frame buffer device\n",
info->node, info->fix.id);
@@ -648,15 +646,15 @@ s1d13xxxfb_probe(struct device *dev)
return 0;
bail:
- s1d13xxxfb_remove(dev);
+ s1d13xxxfb_remove(pdev);
return ret;
}
#ifdef CONFIG_PM
-static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state)
+static int s1d13xxxfb_suspend(struct platform_device *dev, pm_message_t state)
{
- struct fb_info *info = dev_get_drvdata(dev);
+ struct fb_info *info = platform_get_drvdata(dev);
struct s1d13xxxfb_par *s1dfb = info->par;
struct s1d13xxxfb_pdata *pdata = NULL;
@@ -664,8 +662,8 @@ static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state)
lcd_enable(s1dfb, 0);
crt_enable(s1dfb, 0);
- if (dev->platform_data)
- pdata = dev->platform_data;
+ if (dev->dev.platform_data)
+ pdata = dev->dev.platform_data;
#if 0
if (!s1dfb->disp_save)
@@ -701,9 +699,9 @@ static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int s1d13xxxfb_resume(struct device *dev)
+static int s1d13xxxfb_resume(struct platform_device *dev)
{
- struct fb_info *info = dev_get_drvdata(dev);
+ struct fb_info *info = platform_get_drvdata(dev);
struct s1d13xxxfb_par *s1dfb = info->par;
struct s1d13xxxfb_pdata *pdata = NULL;
@@ -714,8 +712,8 @@ static int s1d13xxxfb_resume(struct device *dev)
while ((s1d13xxxfb_readreg(s1dfb, S1DREG_PS_STATUS) & 0x01))
udelay(10);
- if (dev->platform_data)
- pdata = dev->platform_data;
+ if (dev->dev.platform_data)
+ pdata = dev->dev.platform_data;
if (s1dfb->regs_save) {
/* will write RO regs, *should* get away with it :) */
@@ -741,15 +739,16 @@ static int s1d13xxxfb_resume(struct device *dev)
}
#endif /* CONFIG_PM */
-static struct device_driver s1d13xxxfb_driver = {
- .name = S1D_DEVICENAME,
- .bus = &platform_bus_type,
+static struct platform_driver s1d13xxxfb_driver = {
.probe = s1d13xxxfb_probe,
.remove = s1d13xxxfb_remove,
#ifdef CONFIG_PM
.suspend = s1d13xxxfb_suspend,
- .resume = s1d13xxxfb_resume
+ .resume = s1d13xxxfb_resume,
#endif
+ .driver = {
+ .name = S1D_DEVICENAME,
+ },
};
@@ -759,14 +758,14 @@ s1d13xxxfb_init(void)
if (fb_get_options("s1d13xxxfb", NULL))
return -ENODEV;
- return driver_register(&s1d13xxxfb_driver);
+ return platform_driver_register(&s1d13xxxfb_driver);
}
static void __exit
s1d13xxxfb_exit(void)
{
- driver_unregister(&s1d13xxxfb_driver);
+ platform_driver_unregister(&s1d13xxxfb_driver);
}
module_init(s1d13xxxfb_init);
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 855a677..ce6e749 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -634,19 +634,18 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id, struct pt_regs *r)
static char driver_name[]="s3c2410fb";
-int __init s3c2410fb_probe(struct device *dev)
+int __init s3c2410fb_probe(struct platform_device *pdev)
{
struct s3c2410fb_info *info;
struct fb_info *fbinfo;
- struct platform_device *pdev = to_platform_device(dev);
struct s3c2410fb_hw *mregs;
int ret;
int irq;
int i;
- mach_info = dev->platform_data;
+ mach_info = pdev->dev.platform_data;
if (mach_info == NULL) {
- dev_err(dev,"no platform data for lcd, cannot attach\n");
+ dev_err(&pdev->dev,"no platform data for lcd, cannot attach\n");
return -EINVAL;
}
@@ -654,11 +653,11 @@ int __init s3c2410fb_probe(struct device *dev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
- dev_err(dev, "no irq for device\n");
+ dev_err(&pdev->dev, "no irq for device\n");
return -ENOENT;
}
- fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), dev);
+ fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev);
if (!fbinfo) {
return -ENOMEM;
}
@@ -666,7 +665,7 @@ int __init s3c2410fb_probe(struct device *dev)
info = fbinfo->par;
info->fb = fbinfo;
- dev_set_drvdata(dev, fbinfo);
+ platform_set_drvdata(pdev, fbinfo);
s3c2410fb_init_registers(info);
@@ -676,7 +675,7 @@ int __init s3c2410fb_probe(struct device *dev)
memcpy(&info->regs, &mach_info->regs, sizeof(info->regs));
- info->mach_info = dev->platform_data;
+ info->mach_info = pdev->dev.platform_data;
fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
fbinfo->fix.type_aux = 0;
@@ -735,7 +734,7 @@ int __init s3c2410fb_probe(struct device *dev)
ret = request_irq(irq, s3c2410fb_irq, SA_INTERRUPT, pdev->name, info);
if (ret) {
- dev_err(dev, "cannot get irq %d - err %d\n", irq, ret);
+ dev_err(&pdev->dev, "cannot get irq %d - err %d\n", irq, ret);
ret = -EBUSY;
goto release_mem;
}
@@ -773,7 +772,7 @@ int __init s3c2410fb_probe(struct device *dev)
}
/* create device files */
- device_create_file(dev, &dev_attr_debug);
+ device_create_file(&pdev->dev, &dev_attr_debug);
printk(KERN_INFO "fb%d: %s frame buffer device\n",
fbinfo->node, fbinfo->fix.id);
@@ -816,10 +815,9 @@ static void s3c2410fb_stop_lcd(void)
/*
* Cleanup
*/
-static int s3c2410fb_remove(struct device *dev)
+static int s3c2410fb_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct fb_info *fbinfo = dev_get_drvdata(dev);
+ struct fb_info *fbinfo = platform_get_drvdata(pdev);
struct s3c2410fb_info *info = fbinfo->par;
int irq;
@@ -847,9 +845,9 @@ static int s3c2410fb_remove(struct device *dev)
/* suspend and resume support for the lcd controller */
-static int s3c2410fb_suspend(struct device *dev, pm_message_t state)
+static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
{
- struct fb_info *fbinfo = dev_get_drvdata(dev);
+ struct fb_info *fbinfo = platform_get_drvdata(dev);
struct s3c2410fb_info *info = fbinfo->par;
s3c2410fb_stop_lcd();
@@ -864,9 +862,9 @@ static int s3c2410fb_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int s3c2410fb_resume(struct device *dev)
+static int s3c2410fb_resume(struct platform_device *dev)
{
- struct fb_info *fbinfo = dev_get_drvdata(dev);
+ struct fb_info *fbinfo = platform_get_drvdata(dev);
struct s3c2410fb_info *info = fbinfo->par;
clk_enable(info->clk);
@@ -882,24 +880,25 @@ static int s3c2410fb_resume(struct device *dev)
#define s3c2410fb_resume NULL
#endif
-static struct device_driver s3c2410fb_driver = {
- .name = "s3c2410-lcd",
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
+static struct platform_driver s3c2410fb_driver = {
.probe = s3c2410fb_probe,
+ .remove = s3c2410fb_remove,
.suspend = s3c2410fb_suspend,
.resume = s3c2410fb_resume,
- .remove = s3c2410fb_remove
+ .driver = {
+ .name = "s3c2410-lcd",
+ .owner = THIS_MODULE,
+ },
};
int __devinit s3c2410fb_init(void)
{
- return driver_register(&s3c2410fb_driver);
+ return platform_driver_register(&s3c2410fb_driver);
}
static void __exit s3c2410fb_cleanup(void)
{
- driver_unregister(&s3c2410fb_driver);
+ platform_driver_unregister(&s3c2410fb_driver);
}
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index a518457..2ea1354 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -1308,17 +1308,17 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val,
* Power management hooks. Note that we won't be called from IRQ context,
* unlike the blank functions above, so we may sleep.
*/
-static int sa1100fb_suspend(struct device *dev, pm_message_t state)
+static int sa1100fb_suspend(struct platform_device *dev, pm_message_t state)
{
- struct sa1100fb_info *fbi = dev_get_drvdata(dev);
+ struct sa1100fb_info *fbi = platform_get_drvdata(dev);
set_ctrlr_state(fbi, C_DISABLE_PM);
return 0;
}
-static int sa1100fb_resume(struct device *dev)
+static int sa1100fb_resume(struct platform_device *dev)
{
- struct sa1100fb_info *fbi = dev_get_drvdata(dev);
+ struct sa1100fb_info *fbi = platform_get_drvdata(dev);
set_ctrlr_state(fbi, C_ENABLE_PM);
return 0;
@@ -1452,7 +1452,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
return fbi;
}
-static int __init sa1100fb_probe(struct device *dev)
+static int __init sa1100fb_probe(struct platform_device *pdev)
{
struct sa1100fb_info *fbi;
int ret;
@@ -1460,7 +1460,7 @@ static int __init sa1100fb_probe(struct device *dev)
if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
return -EBUSY;
- fbi = sa1100fb_init_fbinfo(dev);
+ fbi = sa1100fb_init_fbinfo(&pdev->dev);
ret = -ENOMEM;
if (!fbi)
goto failed;
@@ -1488,7 +1488,7 @@ static int __init sa1100fb_probe(struct device *dev)
*/
sa1100fb_check_var(&fbi->fb.var, &fbi->fb);
- dev_set_drvdata(dev, fbi);
+ platform_set_drvdata(pdev, fbi);
ret = register_framebuffer(&fbi->fb);
if (ret < 0)
@@ -1505,18 +1505,19 @@ static int __init sa1100fb_probe(struct device *dev)
return 0;
failed:
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
kfree(fbi);
release_mem_region(0xb0100000, 0x10000);
return ret;
}
-static struct device_driver sa1100fb_driver = {
- .name = "sa11x0-fb",
- .bus = &platform_bus_type,
+static struct platform_driver sa1100fb_driver = {
.probe = sa1100fb_probe,
.suspend = sa1100fb_suspend,
.resume = sa1100fb_resume,
+ .driver = {
+ .name = "sa11x0-fb",
+ },
};
int __init sa1100fb_init(void)
@@ -1524,7 +1525,7 @@ int __init sa1100fb_init(void)
if (fb_get_options("sa1100fb", NULL))
return -ENODEV;
- return driver_register(&sa1100fb_driver);
+ return platform_driver_register(&sa1100fb_driver);
}
int __init sa1100fb_setup(char *options)
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
index 34f72ed..646c43f 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/sbuslib.c
@@ -3,6 +3,7 @@
* Copyright (C) 2003 David S. Miller (davem@redhat.com)
*/
+#include <linux/compat.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
@@ -182,3 +183,109 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
};
}
EXPORT_SYMBOL(sbusfb_ioctl_helper);
+
+#ifdef CONFIG_COMPAT
+struct fbcmap32 {
+ int index; /* first element (0 origin) */
+ int count;
+ u32 red;
+ u32 green;
+ u32 blue;
+};
+
+#define FBIOPUTCMAP32 _IOW('F', 3, struct fbcmap32)
+#define FBIOGETCMAP32 _IOW('F', 4, struct fbcmap32)
+
+static int fbiogetputcmap(struct file *file, struct fb_info *info,
+ unsigned int cmd, unsigned long arg)
+{
+ struct fbcmap32 __user *argp = (void __user *)arg;
+ struct fbcmap __user *p = compat_alloc_user_space(sizeof(*p));
+ u32 addr;
+ int ret;
+
+ ret = copy_in_user(p, argp, 2 * sizeof(int));
+ ret |= get_user(addr, &argp->red);
+ ret |= put_user(compat_ptr(addr), &p->red);
+ ret |= get_user(addr, &argp->green);
+ ret |= put_user(compat_ptr(addr), &p->green);
+ ret |= get_user(addr, &argp->blue);
+ ret |= put_user(compat_ptr(addr), &p->blue);
+ if (ret)
+ return -EFAULT;
+ return info->fbops->fb_ioctl(file->f_dentry->d_inode, file,
+ (cmd == FBIOPUTCMAP32) ?
+ FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC,
+ (unsigned long)p, info);
+}
+
+struct fbcursor32 {
+ short set; /* what to set, choose from the list above */
+ short enable; /* cursor on/off */
+ struct fbcurpos pos; /* cursor position */
+ struct fbcurpos hot; /* cursor hot spot */
+ struct fbcmap32 cmap; /* color map info */
+ struct fbcurpos size; /* cursor bit map size */
+ u32 image; /* cursor image bits */
+ u32 mask; /* cursor mask bits */
+};
+
+#define FBIOSCURSOR32 _IOW('F', 24, struct fbcursor32)
+#define FBIOGCURSOR32 _IOW('F', 25, struct fbcursor32)
+
+static int fbiogscursor(struct file *file, struct fb_info *info,
+ unsigned long arg)
+{
+ struct fbcursor __user *p = compat_alloc_user_space(sizeof(*p));
+ struct fbcursor32 __user *argp = (void __user *)arg;
+ compat_uptr_t addr;
+ int ret;
+
+ ret = copy_in_user(p, argp,
+ 2 * sizeof (short) + 2 * sizeof(struct fbcurpos));
+ ret |= copy_in_user(&p->size, &argp->size, sizeof(struct fbcurpos));
+ ret |= copy_in_user(&p->cmap, &argp->cmap, 2 * sizeof(int));
+ ret |= get_user(addr, &argp->cmap.red);
+ ret |= put_user(compat_ptr(addr), &p->cmap.red);
+ ret |= get_user(addr, &argp->cmap.green);
+ ret |= put_user(compat_ptr(addr), &p->cmap.green);
+ ret |= get_user(addr, &argp->cmap.blue);
+ ret |= put_user(compat_ptr(addr), &p->cmap.blue);
+ ret |= get_user(addr, &argp->mask);
+ ret |= put_user(compat_ptr(addr), &p->mask);
+ ret |= get_user(addr, &argp->image);
+ ret |= put_user(compat_ptr(addr), &p->image);
+ if (ret)
+ return -EFAULT;
+ return info->fbops->fb_ioctl(file->f_dentry->d_inode, file,
+ FBIOSCURSOR, (unsigned long)p, info);
+}
+
+long sbusfb_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg, struct fb_info *info)
+{
+ switch (cmd) {
+ case FBIOGTYPE:
+ case FBIOSATTR:
+ case FBIOGATTR:
+ case FBIOSVIDEO:
+ case FBIOGVIDEO:
+ case FBIOGCURSOR32: /* This is not implemented yet.
+ Later it should be converted... */
+ case FBIOSCURPOS:
+ case FBIOGCURPOS:
+ case FBIOGCURMAX:
+ return info->fbops->fb_ioctl(file->f_dentry->d_inode,
+ file, cmd, arg, info);
+ case FBIOPUTCMAP32:
+ return fbiogetputcmap(file, info, cmd, arg);
+ case FBIOGETCMAP32:
+ return fbiogetputcmap(file, info, cmd, arg);
+ case FBIOSCURSOR32:
+ return fbiogscursor(file, info, arg);
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+EXPORT_SYMBOL(sbusfb_compat_ioctl);
+#endif
diff --git a/drivers/video/sbuslib.h b/drivers/video/sbuslib.h
index a6aa33b..b470e52 100644
--- a/drivers/video/sbuslib.h
+++ b/drivers/video/sbuslib.h
@@ -20,5 +20,7 @@ extern int sbusfb_mmap_helper(struct sbus_mmap_map *map,
int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
struct fb_info *info,
int type, int fb_depth, unsigned long fb_size);
+long sbusfb_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg, struct fb_info *info);
#endif /* _SBUSLIB_H */
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index 2e8769d..7054660 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -750,9 +750,8 @@ int __init sgivwfb_setup(char *options)
/*
* Initialisation
*/
-static int __init sgivwfb_probe(struct device *device)
+static int __init sgivwfb_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(device);
struct sgivw_par *par;
struct fb_info *info;
char *monitor;
@@ -813,7 +812,7 @@ static int __init sgivwfb_probe(struct device *device)
goto fail_register_framebuffer;
}
- dev_set_drvdata(&dev->dev, info);
+ platform_set_drvdata(dev, info);
printk(KERN_INFO "fb%d: SGI DBE frame buffer device, using %ldK of video memory at %#lx\n",
info->node, sgivwfb_mem_size >> 10, sgivwfb_mem_phys);
@@ -831,9 +830,9 @@ fail_ioremap_regs:
return -ENXIO;
}
-static int sgivwfb_remove(struct device *device)
+static int sgivwfb_remove(struct platform_device *dev)
{
- struct fb_info *info = dev_get_drvdata(device);
+ struct fb_info *info = platform_get_drvdata(dev);
if (info) {
struct sgivw_par *par = info->par;
@@ -847,11 +846,12 @@ static int sgivwfb_remove(struct device *device)
return 0;
}
-static struct device_driver sgivwfb_driver = {
- .name = "sgivwfb",
- .bus = &platform_bus_type,
+static struct platform_driver sgivwfb_driver = {
.probe = sgivwfb_probe,
.remove = sgivwfb_remove,
+ .driver = {
+ .name = "sgivwfb",
+ },
};
static struct platform_device *sgivwfb_device;
@@ -867,7 +867,7 @@ int __init sgivwfb_init(void)
return -ENODEV;
sgivwfb_setup(option);
#endif
- ret = driver_register(&sgivwfb_driver);
+ ret = platform_driver_register(&sgivwfb_driver);
if (!ret) {
sgivwfb_device = platform_device_alloc("sgivwfb", 0);
if (sgivwfb_device) {
@@ -875,7 +875,7 @@ int __init sgivwfb_init(void)
} else
ret = -ENOMEM;
if (ret) {
- driver_unregister(&sgivwfb_driver);
+ platform_driver_unregister(&sgivwfb_driver);
platform_device_put(sgivwfb_device);
}
}
@@ -890,7 +890,7 @@ MODULE_LICENSE("GPL");
static void __exit sgivwfb_exit(void)
{
platform_device_unregister(sgivwfb_device);
- driver_unregister(&sgivwfb_driver);
+ platform_driver_unregister(&sgivwfb_driver);
}
module_exit(sgivwfb_exit);
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 59fff29..fe4f63f 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -52,6 +52,9 @@ static struct fb_ops tcx_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = tcx_mmap,
.fb_ioctl = tcx_ioctl,
+#ifdef CONFIG_COMPAT
+ .fb_compat_ioctl = sbusfb_compat_ioctl,
+#endif
};
/* THC definitions */
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index e25eae1..3e58ddc 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -245,9 +245,8 @@ static int __init vesafb_setup(char *options)
return 0;
}
-static int __init vesafb_probe(struct device *device)
+static int __init vesafb_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(device);
struct fb_info *info;
int i, err;
unsigned int size_vmode;
@@ -414,6 +413,7 @@ static int __init vesafb_probe(struct device *device)
* region already (FIXME) */
request_region(0x3c0, 32, "vesafb");
+#ifdef CONFIG_MTRR
if (mtrr) {
unsigned int temp_size = size_total;
unsigned int type = 0;
@@ -451,6 +451,7 @@ static int __init vesafb_probe(struct device *device)
} while (temp_size >= PAGE_SIZE && rc == -EINVAL);
}
}
+#endif
info->fbops = &vesafb_ops;
info->var = vesafb_defined;
@@ -480,10 +481,11 @@ err:
return err;
}
-static struct device_driver vesafb_driver = {
- .name = "vesafb",
- .bus = &platform_bus_type,
+static struct platform_driver vesafb_driver = {
.probe = vesafb_probe,
+ .driver = {
+ .name = "vesafb",
+ },
};
static struct platform_device vesafb_device = {
@@ -498,12 +500,12 @@ static int __init vesafb_init(void)
/* ignore error return of fb_get_options */
fb_get_options("vesafb", &option);
vesafb_setup(option);
- ret = driver_register(&vesafb_driver);
+ ret = platform_driver_register(&vesafb_driver);
if (!ret) {
ret = platform_device_register(&vesafb_device);
if (ret)
- driver_unregister(&vesafb_driver);
+ platform_driver_unregister(&vesafb_driver);
}
return ret;
}
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 8794dc5..ffa1ad4 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -403,9 +403,8 @@ static void vfb_platform_release(struct device *device)
// This is called when the reference count goes to zero.
}
-static int __init vfb_probe(struct device *device)
+static int __init vfb_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(device);
struct fb_info *info;
int retval = -ENOMEM;
@@ -447,7 +446,7 @@ static int __init vfb_probe(struct device *device)
retval = register_framebuffer(info);
if (retval < 0)
goto err2;
- dev_set_drvdata(&dev->dev, info);
+ platform_set_drvdata(dev, info);
printk(KERN_INFO
"fb%d: Virtual frame buffer device, using %ldK of video memory\n",
@@ -462,9 +461,9 @@ err:
return retval;
}
-static int vfb_remove(struct device *device)
+static int vfb_remove(struct platform_device *dev)
{
- struct fb_info *info = dev_get_drvdata(device);
+ struct fb_info *info = platform_get_drvdata(dev);
if (info) {
unregister_framebuffer(info);
@@ -474,11 +473,12 @@ static int vfb_remove(struct device *device)
return 0;
}
-static struct device_driver vfb_driver = {
- .name = "vfb",
- .bus = &platform_bus_type,
+static struct platform_driver vfb_driver = {
.probe = vfb_probe,
.remove = vfb_remove,
+ .driver = {
+ .name = "vfb",
+ },
};
static struct platform_device vfb_device = {
@@ -504,12 +504,12 @@ static int __init vfb_init(void)
if (!vfb_enable)
return -ENXIO;
- ret = driver_register(&vfb_driver);
+ ret = platform_driver_register(&vfb_driver);
if (!ret) {
ret = platform_device_register(&vfb_device);
if (ret)
- driver_unregister(&vfb_driver);
+ platform_driver_unregister(&vfb_driver);
}
return ret;
}
@@ -520,7 +520,7 @@ module_init(vfb_init);
static void __exit vfb_exit(void)
{
platform_device_unregister(&vfb_device);
- driver_unregister(&vfb_driver);
+ platform_driver_unregister(&vfb_driver);
}
module_exit(vfb_exit);
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 48e70f1..f6e24ee 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -437,9 +437,9 @@ static void w100fb_restore_vidmem(struct w100fb_par *par)
}
}
-static int w100fb_suspend(struct device *dev, pm_message_t state)
+static int w100fb_suspend(struct platform_device *dev, pm_message_t state)
{
- struct fb_info *info = dev_get_drvdata(dev);
+ struct fb_info *info = platform_get_drvdata(dev);
struct w100fb_par *par=info->par;
struct w100_tg_info *tg = par->mach->tg;
@@ -452,9 +452,9 @@ static int w100fb_suspend(struct device *dev, pm_message_t state)
return 0;
}
-static int w100fb_resume(struct device *dev)
+static int w100fb_resume(struct platform_device *dev)
{
- struct fb_info *info = dev_get_drvdata(dev);
+ struct fb_info *info = platform_get_drvdata(dev);
struct w100fb_par *par=info->par;
struct w100_tg_info *tg = par->mach->tg;
@@ -473,13 +473,12 @@ static int w100fb_resume(struct device *dev)
#endif
-int __init w100fb_probe(struct device *dev)
+int __init w100fb_probe(struct platform_device *pdev)
{
int err = -EIO;
struct w100fb_mach_info *inf;
struct fb_info *info = NULL;
struct w100fb_par *par;
- struct platform_device *pdev = to_platform_device(dev);
struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
unsigned int chip_id;
@@ -515,16 +514,16 @@ int __init w100fb_probe(struct device *dev)
if (remapped_fbuf == NULL)
goto out;
- info=framebuffer_alloc(sizeof(struct w100fb_par), dev);
+ info=framebuffer_alloc(sizeof(struct w100fb_par), &pdev->dev);
if (!info) {
err = -ENOMEM;
goto out;
}
par = info->par;
- dev_set_drvdata(dev, info);
+ platform_set_drvdata(pdev, info);
- inf = dev->platform_data;
+ inf = pdev->dev.platform_data;
par->chip_id = chip_id;
par->mach = inf;
par->fastpll_mode = 0;
@@ -600,10 +599,10 @@ int __init w100fb_probe(struct device *dev)
goto out;
}
- device_create_file(dev, &dev_attr_fastpllclk);
- device_create_file(dev, &dev_attr_reg_read);
- device_create_file(dev, &dev_attr_reg_write);
- device_create_file(dev, &dev_attr_flip);
+ device_create_file(&pdev->dev, &dev_attr_fastpllclk);
+ device_create_file(&pdev->dev, &dev_attr_reg_read);
+ device_create_file(&pdev->dev, &dev_attr_reg_write);
+ device_create_file(&pdev->dev, &dev_attr_flip);
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
return 0;
@@ -622,15 +621,15 @@ out:
}
-static int w100fb_remove(struct device *dev)
+static int w100fb_remove(struct platform_device *pdev)
{
- struct fb_info *info = dev_get_drvdata(dev);
+ struct fb_info *info = platform_get_drvdata(pdev);
struct w100fb_par *par=info->par;
- device_remove_file(dev, &dev_attr_fastpllclk);
- device_remove_file(dev, &dev_attr_reg_read);
- device_remove_file(dev, &dev_attr_reg_write);
- device_remove_file(dev, &dev_attr_flip);
+ device_remove_file(&pdev->dev, &dev_attr_fastpllclk);
+ device_remove_file(&pdev->dev, &dev_attr_reg_read);
+ device_remove_file(&pdev->dev, &dev_attr_reg_write);
+ device_remove_file(&pdev->dev, &dev_attr_flip);
unregister_framebuffer(info);
@@ -1448,23 +1447,24 @@ static void w100_vsync(void)
writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
}
-static struct device_driver w100fb_driver = {
- .name = "w100fb",
- .bus = &platform_bus_type,
+static struct platform_driver w100fb_driver = {
.probe = w100fb_probe,
.remove = w100fb_remove,
.suspend = w100fb_suspend,
.resume = w100fb_resume,
+ .driver = {
+ .name = "w100fb",
+ },
};
int __devinit w100fb_init(void)
{
- return driver_register(&w100fb_driver);
+ return platform_driver_register(&w100fb_driver);
}
void __exit w100fb_cleanup(void)
{
- driver_unregister(&w100fb_driver);
+ platform_driver_unregister(&w100fb_driver);
}
module_init(w100fb_init);
OpenPOWER on IntegriCloud